// If bound_below (bound_above) is not indeterminate it is a value which the condition value // is known top be greater than (less than or equal) void MultiWayGroupList::generate_code(StatementList *x) { // start by trying to merge blocks bool closed = false; while (!closed) { closed = true; size_t i = 0; while (i + 1 < _list.length()) { MultiWayGroup *low = _list[i]; MultiWayGroup *high = _list[i + 1]; double density = (double)(low->get_label_count() + high->get_label_count()) /(high->get_high_bound() - low->get_low_bound() + 1).c_double(); if (density >= required_density) { low->merge(*high); delete high->get_statement(); delete high; _list.erase(i + 1); closed = false; i++; // skip over element we just removed } i ++; } } generate_code_subgroup(x,IInteger(),IInteger(),0,_list.length() - 1); }
CForStatement* make_strip(SuifEnv *env, VariableSymbol* loop_counter, int upper_bound, int step_size, Statement* body) { TypeBuilder *type_builder = get_type_builder(env); Statement *before_stmt = create_store_variable_statement(env, loop_counter, create_int_constant(env, IInteger(0))); Expression *test_expr = create_binary_expression(env, type_builder->get_boolean_type(), "is_less_than", create_var_use(loop_counter), create_int_constant(env, IInteger(upper_bound))); Expression *step_expr = create_binary_expression(env, loop_counter->get_type()->get_base_type(), "add", create_var_use(loop_counter), create_int_constant(env, IInteger(step_size))); Statement *step_stmt = create_store_variable_statement(env, loop_counter, step_expr); return create_c_for_statement(env, before_stmt, test_expr, step_stmt, body); }
void MarkRedundantPass::do_procedure_definition(ProcedureDefinition* proc_def) { procDef = proc_def ; assert(procDef != NULL) ; OutputInformation("Marking a redundant label") ; list<LabelLocationStatement*>* allLabels = collect_objects<LabelLocationStatement>(procDef->get_body()) ; list<LabelLocationStatement*>::iterator labelIter = allLabels->begin() ; while (labelIter != allLabels->end()) { if ((*labelIter)->get_defined_label()->get_name() == redundantLabel) { BrickAnnote* labelBrick = create_brick_annote(theEnv, "Redundant") ; IntegerBrick* doubleBrick = create_integer_brick(theEnv, IInteger(doubleOrTriple)) ; labelBrick->append_brick(doubleBrick) ; (*labelIter)->append_annote(labelBrick) ; } ++labelIter ; } delete allLabels ; OutputInformation("Done marking a redundant label") ; }
void SingleInheritanceVtbls:: attach_vtbl_slot_number_annotes( SingleInheritanceClassType* ctype ) { vtbl_t* vtbl = build_vtbls( ctype ); unsigned vtbl_size = vtbl->size(); for ( unsigned i = 0 ; i < vtbl_size ; i++ ) { InstanceMethodSymbol* msym = (*vtbl)[i]; ::attach_vtbl_slot_number_annote( _env, msym, IInteger(i) ); } }
DataType* ExportPass::CloneDataType(DataType* t) { assert(t != NULL) ; PointerType* pointerClone = dynamic_cast<PointerType*>(t) ; ReferenceType* referenceClone = dynamic_cast<ReferenceType*>(t) ; ArrayType* arrayClone = dynamic_cast<ArrayType*>(t) ; if (pointerClone != NULL) { QualifiedType* refType = dynamic_cast<QualifiedType*>(pointerClone->get_reference_type()) ; assert(refType != NULL) ; DataType* cloneType = CloneDataType(refType->get_base_type()) ; assert(cloneType != NULL) ; return create_pointer_type(theEnv, IInteger(32), 0, create_qualified_type(theEnv, cloneType)) ; } if (referenceClone != NULL) { QualifiedType* refType = dynamic_cast<QualifiedType*>(referenceClone->get_reference_type()) ; assert(refType != NULL) ; DataType* clonedType = CloneDataType(refType->get_base_type()) ; return create_reference_type(theEnv, IInteger(32), 0, create_qualified_type(theEnv, clonedType)) ; } if (arrayClone != NULL) { QualifiedType* elementType = arrayClone->get_element_type() ; DataType* internalType = CloneDataType(elementType->get_base_type()) ; QualifiedType* finalQual = create_qualified_type(theEnv, internalType) ; return create_pointer_type(theEnv, IInteger(32), 0, finalQual) ; } return dynamic_cast<DataType*>(t->deep_clone()) ; }
MultiValueBlock* NodeBuilder::new_cstr_value_block(String s) { ArrayType* type = _type_builder->get_array_type(get_qualified_type(get_char_type()), IInteger(0), IInteger(s.length()+1)); MultiValueBlock* mb = create_multi_value_block(_suif_env, type); IInteger charlen = get_char_type()->get_bit_size(); IInteger offset(0); for (int i =0; i<s.length(); i++) { mb->add_sub_block(offset, create_expression_value_block(_suif_env, char_const(s[i]))); offset += charlen; } mb->add_sub_block(offset, create_expression_value_block(_suif_env, char_const('\0'))); return mb; }
static Expression *build_empty_expression(DataType *t) { SuifEnv *s = t->get_suif_env(); suif_assert_message(!is_kind_of<GroupType>(t), ("build_empty_expression:: can not handle GroupType")); if (is_kind_of<VoidType>(t)) return(NULL); if (is_kind_of<IntegerType>(t)) { IntConstant *c = create_int_constant(s, t, IInteger(0)); return c; } // This works for Int, Float, Enum, pointers TypeBuilder *tb = get_type_builder(s); IntegerType *it = tb->get_integer_type(); IntConstant *c = create_int_constant(s, it, IInteger(0)); Expression *cvt = create_unary_expression(s, t, k_convert, c); return(cvt); }
/** Create an expression for byte offset of a group field. * */ Expression* NodeBuilder::get_field_offset_exp(FieldSymbol* fsym) { Expression *boffset = fsym->get_bit_offset(); if (!is_kind_of<IntConstant>(boffset)) { trash(fsym); SUIF_THROW(SuifException(String("Field offset not in IntConstant ") + to_id_string(fsym))); } IInteger v = to<IntConstant>(boffset)->get_value(); return int_const(v.div(IInteger(BITSPERBYTE))); }
IntConstant* build_vtbl_slot_count_int_constant( SuifEnv* env, ClassType* owning_class ) { TypeBuilder* tb = get_type_builder( env ); IntConstant* icnst = ::create_int_constant( env, tb->get_integer_type( true ), // result_type IInteger() // value: inserted later ); attach_vtbl_slot_count_annote( env, icnst, owning_class ); return icnst; }
IntConstant* build_vtbl_slot_int_constant( SuifEnv* env, InstanceMethodSymbol* msym ) { TypeBuilder* tb = get_type_builder( env ); IntConstant* icnst = ::create_int_constant( env, tb->get_integer_type( true ), // result_type IInteger() // value: inserted later ); attach_vtbl_slot_annote( env, icnst, msym ); return icnst; }
/* * The default type of a vtbl slot is void* [ <vtbl-size> ]. */ DataType* SingleInheritanceVtbls::get_vtbl_type( SingleInheritanceClassType* ctype, IInteger vtbl_size ) { DataType* slot_type = vtbl_slot_type( ctype ); QualifiedType* q_slot_type = _tb->get_qualified_type( slot_type ); ArrayType* vtbl_type = _tb->get_array_type( q_slot_type, IInteger(0), (vtbl_size - 1) ); return vtbl_type; }
void ExportPass::ConstructModuleSymbols() { CProcedureType* originalType = dynamic_cast<CProcedureType*>(originalProcedure->get_procedure_symbol()->get_type()) ; assert(originalType != NULL) ; // The original type takes and returns a struct. We need to change this // to a list of arguments. VoidType* newReturnType = create_void_type(theEnv, IInteger(0), 0) ; constructedType = create_c_procedure_type(theEnv, newReturnType, false, // has varargs true, // arguments_known 0, // bit alignment LString("ConstructedType")) ; StructType* returnType = dynamic_cast<StructType*>(originalType->get_result_type()) ; assert(returnType != NULL) ; SymbolTable* structSymTab = returnType->get_group_symbol_table() ; assert(structSymTab != NULL) ; for (int i = 0 ; i < structSymTab->get_symbol_table_object_count() ; ++i) { VariableSymbol* nextVariable = dynamic_cast<VariableSymbol*>(structSymTab->get_symbol_table_object(i)); if (nextVariable != NULL) { // Check to see if this is an output or not QualifiedType* cloneType ; DataType* cloneBase = dynamic_cast<DataType*>(nextVariable->get_type()->get_base_type()->deep_clone()) ; assert(cloneBase != NULL) ; cloneType = create_qualified_type(theEnv, cloneBase) ; if (nextVariable->lookup_annote_by_name("Output") != NULL) { cloneType->append_annote(create_brick_annote(theEnv, "Output")) ; // Why doesn't this stick around? } constructedType->append_argument(cloneType) ; } } constructedSymbol = create_procedure_symbol(theEnv, constructedType, originalProcedure->get_procedure_symbol()->get_name()) ; constructedSymbol->set_definition(NULL) ; }
void solve_li_c_for_stmt(Statement *s){ SuifEnv *env = s->get_suif_env(); CForStatement *c_for_stmt = to<CForStatement>(s); BrickAnnote *nest_level = to<BrickAnnote>(s->lookup_annote_by_name("c_for_info")); if(nest_level->get_brick_count() == 0){ nest_level->insert_brick(0, create_integer_brick(env, IInteger(++loop_level))); BrickAnnote *loop_label = to<BrickAnnote>(s->lookup_annote_by_name("c_for_label")); if(loop_label->get_brick_count() == 0){ loop_label->insert_brick(0, create_string_brick(env, String(loop_level))); } } Statement *body = c_for_stmt->get_body(); solve_li_statement(body); --loop_level; }
void CleanupBoolSelsPass::do_procedure_definition(ProcedureDefinition* p) { procDef = p ; assert(procDef != NULL) ; OutputInformation("Cleanup Boolean Select Pass Begins") ; // Find all of the locations that have been marked as "UndefinedPath" Annote* functionAnnote = procDef->lookup_annote_by_name("FunctionType") ; BrickAnnote* functionBrickAnnote = dynamic_cast<BrickAnnote*>(functionAnnote) ; assert(functionBrickAnnote != NULL) ; IntegerBrick* valueBrick = dynamic_cast<IntegerBrick*>(functionBrickAnnote->get_brick(0)) ; assert(valueBrick != NULL) ; int myType = valueBrick->get_value().c_int() ; if (myType == MODULE) { // Find all of the expressions marked "UndefinedPath" and replace with // the integer constant zero. list<Expression*>* allExpr = collect_objects<Expression>(procDef->get_body()) ; list<Expression*>::iterator exprIter = allExpr->begin() ; while (exprIter != allExpr->end()) { if ((*exprIter)->lookup_annote_by_name("UndefinedPath") != NULL) { Expression* zero = create_int_constant(theEnv, (*exprIter)->get_result_type(), IInteger(0)) ; (*exprIter)->get_parent()->replace((*exprIter), zero) ; } ++exprIter ; } delete allExpr ; } OutputInformation("Cleanup Boolean Select Pass Ends") ; }
/* * Constructs the actual vtbl. * A vtbl is implemented as an array of pointers that point to * the addresses of the dispatched methods. * A method address is kept in a ExpressionValueBlock. * * The VariableDefinition that holds the array is returned. It * must be * - inserted into a DefinitionBlock * - attached to a VariableSymbol. */ VariableDefinition* SingleInheritanceVtbls::get_vtbl( SingleInheritanceClassType* ctype ) { vtbl_t* vtbl = build_vtbls( ctype ); unsigned vtbl_size = vtbl->size(); // DataType* slot_type = vtbl_slot_type( ctype ); // QualifiedType* q_slot_type = _tb->get_qualified_type( slot_type ); DataType* vtbl_type = get_vtbl_type( ctype, vtbl_size ); // _tb->get_array_type( q_slot_type, // IInteger(0), // IInteger(vtbl_size - 1) ); MultiValueBlock* mvb = ::create_multi_value_block( _env, vtbl_type ); for ( unsigned i = 0 ; i < vtbl_size ; i++ ) { InstanceMethodSymbol* msym = (*vtbl)[i]; ::attach_vtbl_slot_number_annote( _env, msym, IInteger(i) ); ProcedureType* mtype = msym->get_type(); PointerType* ptr_to_mtype = get_pointer_type( _env, mtype ); SymbolAddressExpression* sa_expr = ::create_symbol_address_expression( _env, ptr_to_mtype, msym ); msym->set_is_address_taken( true ); ExpressionValueBlock* evb = ::create_expression_value_block( _env, sa_expr ); append_to_multi_value_block( mvb, evb ); } return ::create_variable_definition( _env, NULL, // variable_symbol 0, // @@@ bit_alignment mvb, true // is_static ); }
Constant* MiniConstantPropagationPass::Merge(Constant* x, Constant* y, LString opcode) { assert(theEnv != NULL) ; if (x == NULL || y == NULL) { return NULL ; } IntConstant* xInt = dynamic_cast<IntConstant*>(x) ; IntConstant* yInt = dynamic_cast<IntConstant*>(y) ; FloatConstant* xFloat = dynamic_cast<FloatConstant*>(x) ; FloatConstant* yFloat = dynamic_cast<FloatConstant*>(y) ; // This mini propagation only cares for addition and subtraction. Other // propagations will be handled in a later pass. if (opcode == LString("add")) { if (xInt != NULL && yInt != NULL) { int mergedValue = xInt->get_value().c_int() + yInt->get_value().c_int() ; return create_int_constant(theEnv, xInt->get_result_type(), IInteger(mergedValue)) ; } if (xFloat != NULL && yFloat != NULL) { float mergedValue = StringToFloat(xFloat->get_value()) + StringToFloat(yFloat->get_value()) ; return create_float_constant(theEnv, xFloat->get_result_type(), FloatToString(mergedValue)) ; } if (xInt != NULL && yFloat != NULL) { float mergedValue = xInt->get_value().c_int() + StringToFloat(yFloat->get_value()) ; return create_float_constant(theEnv, yFloat->get_result_type(), FloatToString(mergedValue)) ; } if (xFloat != NULL && yInt != NULL) { float mergedValue = StringToFloat(xFloat->get_value()) + yInt->get_value().c_int() ; return create_float_constant(theEnv, xFloat->get_result_type(), FloatToString(mergedValue)) ; } } if (opcode == LString("subtract")) { if (xInt != NULL && yInt != NULL) { int mergedValue = xInt->get_value().c_int() - yInt->get_value().c_int() ; return create_int_constant(theEnv, xInt->get_result_type(), IInteger(mergedValue)) ; } if (xFloat != NULL && yFloat != NULL) { float mergedValue = StringToFloat(xFloat->get_value()) - StringToFloat(yFloat->get_value()) ; return create_float_constant(theEnv, xFloat->get_result_type(), FloatToString(mergedValue)) ; } if (xInt != NULL && yFloat != NULL) { float mergedValue = xInt->get_value().c_int() - StringToFloat(yFloat->get_value()) ; return create_float_constant(theEnv, yFloat->get_result_type(), FloatToString(mergedValue)) ; } if (xFloat != NULL && yInt != NULL) { float mergedValue = StringToFloat(xFloat->get_value()) - yInt->get_value().c_int() ; return create_float_constant(theEnv, xFloat->get_result_type(), FloatToString(mergedValue)) ; } } return NULL ; }
void TransformSystemsToModules::Transform() { assert(procDef != NULL) ; // Collect all the input scalars and output scalars list<VariableSymbol*> ports ; SymbolTable* procSymTab = procDef->get_symbol_table() ; bool foundInputs = false ; bool foundOutputs = false ; for (int i = 0 ; i < procSymTab->get_symbol_table_object_count() ; ++i) { SymbolTableObject* nextObject = procSymTab->get_symbol_table_object(i) ; if (nextObject->lookup_annote_by_name("InputScalar") != NULL) { VariableSymbol* toConvert = dynamic_cast<VariableSymbol*>(nextObject) ; assert(toConvert != NULL) ; LString inputName = toConvert->get_name() ; inputName = inputName + "_in" ; toConvert->set_name(inputName) ; ports.push_back(toConvert) ; foundInputs = true ; } if (nextObject->lookup_annote_by_name("OutputVariable") != NULL) { VariableSymbol* toConvert = dynamic_cast<VariableSymbol*>(nextObject) ; assert(toConvert != NULL) ; LString outputName = toConvert->get_name() ; outputName = outputName + "_out" ; toConvert->set_name(outputName) ; ports.push_back(toConvert) ; foundOutputs = true ; } } assert(foundInputs && "Could not identify inputs. Were they removed via optimizations?") ; assert(foundOutputs && "Could not identify outputs. Were they removed via optimizations?") ; // Determine the bit size and add everything to a new symbol table int bitSize = 0 ; GroupSymbolTable* structTable = create_group_symbol_table(theEnv, procDef->get_symbol_table()) ; std::map<VariableSymbol*, FieldSymbol*> replacementFields ; bool portsRemoved = false ; // If this was actually a new style module, we should make sure to // put these in the correct order. if (isModule(procDef)) { // Go through the original symbol table and remove any parameter // symbols that originally existed SymbolTable* originalSymTab = procDef->get_symbol_table() ; Iter<SymbolTableObject*> originalIter = originalSymTab->get_symbol_table_object_iterator() ; while (originalIter.is_valid()) { SymbolTableObject* currentObj = originalIter.current() ; originalIter.next() ; if (dynamic_cast<ParameterSymbol*>(currentObj) != NULL) { originalSymTab->remove_symbol_table_object(currentObj) ; } } portsRemoved = true ; // Sort the variable symbols in parameter order. This is just an // insertion sort, so it could be done faster. list<VariableSymbol*> sortedPorts ; for (int i = 0 ; i < ports.size() ; ++i) { list<VariableSymbol*>::iterator portIter = ports.begin() ; while (portIter != ports.end()) { BrickAnnote* orderAnnote = dynamic_cast<BrickAnnote*>((*portIter)-> lookup_annote_by_name("ParameterOrder")) ; if (orderAnnote == NULL) { ++portIter ; continue ; } IntegerBrick* orderBrick = dynamic_cast<IntegerBrick*>(orderAnnote->get_brick(0)) ; assert(orderBrick != NULL) ; if (orderBrick->get_value().c_int() == i) { sortedPorts.push_back(*portIter) ; break ; } ++portIter ; } } if (sortedPorts.size() != ports.size()) { OutputWarning("Warning! Analysis detected some input scalars not in" " the parameter list") ; } // Replace ports with sortedPorts ports = sortedPorts ; } list<VariableSymbol*>::iterator portIter = ports.begin() ; while (portIter != ports.end()) { bitSize += (*portIter)->get_type()->get_base_type()->get_bit_size().c_int() ; LString dupeName = (*portIter)->get_name() ; // Create offset expression: IntConstant* offset = create_int_constant(theEnv, create_data_type(theEnv, IInteger(32), 0), IInteger(bitSize)) ; QualifiedType* dupeType = (*portIter)->get_type() ; // Deal with the case where reference types were passed in ReferenceType* refType = dynamic_cast<ReferenceType*>(dupeType->get_base_type()) ; while (refType != NULL) { dupeType = dynamic_cast<QualifiedType*>(refType->get_reference_type()) ; assert(dupeType != NULL) ; refType = dynamic_cast<ReferenceType*>(dupeType->get_base_type()) ; } // Create a new variable symbol clone FieldSymbol* dupe = create_field_symbol(theEnv, dupeType, offset, dupeName) ; structTable->append_symbol_table_object(dupe) ; // Make the connection with the duplicated symbol replacementFields[(*portIter)] = dupe ; // Remove the original variable symbol from the procedure definition // symbol table. if (!portsRemoved) { procDef->get_symbol_table()->remove_symbol_table_object(*portIter) ; } ++portIter ; } assert(bitSize != 0); StructType* moduleStruct = create_struct_type(theEnv, IInteger(bitSize), 0, // bit_alignment TempName(procDef->get_procedure_symbol()->get_name()), 0, // is_complete structTable) ; Iter<FileBlock*> fBlocks = theEnv->get_file_set_block()->get_file_block_iterator() ; assert(fBlocks.is_valid()) ; (fBlocks.current())->get_symbol_table()->append_symbol_table_object(moduleStruct) ; // This is commented out because it is in the file state block //procDef->get_symbol_table()->append_symbol_table_object(moduleStruct) ; QualifiedType* qualifiedModuleStruct = create_qualified_type(theEnv, moduleStruct, TempName(LString("qualifiedModuleStruct"))) ; procDef->get_symbol_table()->append_symbol_table_object(qualifiedModuleStruct) ; // Create an instance of this type and add it to the symbol table. ParameterSymbol* structInstance = create_parameter_symbol(theEnv, qualifiedModuleStruct, TempName(LString("structInstance"))) ; procDef->get_symbol_table()->append_symbol_table_object(structInstance) ; // Now, set up the procedure symbol to take the struct and return the // struct. assert(procDef != NULL) ; ProcedureSymbol* procSym = procDef->get_procedure_symbol() ; assert(procSym != NULL) ; ProcedureType* procType = procSym->get_type() ; assert(procType != NULL) ; CProcedureType* cProcType = dynamic_cast<CProcedureType*>(procType) ; assert(cProcType != NULL) ; // Instead of appending the struct argument, we need to replace all of the // arguments with the struct. while (cProcType->get_argument_count() > 0) { cProcType->remove_argument(0) ; } cProcType->set_result_type(moduleStruct) ; cProcType->append_argument(qualifiedModuleStruct) ; // Now go through all load variable expressions and replace them all with // field symbol values if appropriate list<LoadVariableExpression*>* allLoads = collect_objects<LoadVariableExpression>(procDef->get_body()) ; list<LoadVariableExpression*>::iterator loadIter = allLoads->begin() ; while (loadIter != allLoads->end()) { VariableSymbol* currentVariable = (*loadIter)->get_source() ; if (replacementFields.find(currentVariable) != replacementFields.end()) { (*loadIter)->set_source(replacementFields[currentVariable]) ; } ++loadIter ; } delete allLoads ; // Also replace all of the definitions with the field symbol list<StoreVariableStatement*>* allStoreVars = collect_objects<StoreVariableStatement>(procDef->get_body()) ; list<StoreVariableStatement*>::iterator storeVarIter = allStoreVars->begin(); while (storeVarIter != allStoreVars->end()) { VariableSymbol* currentDest = (*storeVarIter)->get_destination() ; if (replacementFields.find(currentDest) != replacementFields.end()) { (*storeVarIter)->set_destination(replacementFields[currentDest]) ; } ++storeVarIter ; } delete allStoreVars ; list<SymbolAddressExpression*>* allSymAddr = collect_objects<SymbolAddressExpression>(procDef->get_body()) ; list<SymbolAddressExpression*>::iterator symAddrIter = allSymAddr->begin() ; while (symAddrIter != allSymAddr->end()) { VariableSymbol* currentVar = dynamic_cast<VariableSymbol*>((*symAddrIter)->get_addressed_symbol()) ; if (currentVar != NULL && replacementFields.find(currentVar) != replacementFields.end()) { (*symAddrIter)->set_addressed_symbol(replacementFields[currentVar]) ; } ++symAddrIter ; } delete allSymAddr ; // One final for bool selects list<CallStatement*>* allCalls = collect_objects<CallStatement>(procDef->get_body()) ; list<CallStatement*>::iterator callIter = allCalls->begin() ; while(callIter != allCalls->end()) { VariableSymbol* currentVar = (*callIter)->get_destination() ; if (currentVar != NULL && replacementFields.find(currentVar) != replacementFields.end()) { (*callIter)->set_destination(replacementFields[currentVar]) ; } ++callIter ; } delete allCalls ; }
IntConstant* NodeBuilder::bool_const(bool v) { return int_const(IInteger(v ? 1 : 0)); }
IntConstant* NodeBuilder::int_const(int i) { return int_const(IInteger(i)); }