StructType* NodeBuilder::new_struct_type(LString name) { GroupSymbolTable* gtab = create_group_symbol_table(_suif_env); StructType* stype = create_struct_type(_suif_env, 0, sizeof(int), name, true, gtab); _symtab->add_symbol(stype); return stype; }
/* Synthesize a CALL_EXPR and a TRY_FINALLY_EXPR, for this chain of _DECLs if appropriate. Arrange to call the __mf_register function now, and the __mf_unregister function later for each. Return the gimple sequence after synthesis. */ gimple_seq mx_register_decls (tree decl, gimple_seq seq, gimple stmt, location_t location, bool func_args) { gimple_seq finally_stmts = NULL; gimple_stmt_iterator initially_stmts = gsi_start (seq); bool sframe_inserted = false; size_t front_rz_size, rear_rz_size; tree fsize, rsize, size; gimple uninit_fncall_front, uninit_fncall_rear, init_fncall_front, \ init_fncall_rear, init_assign_stmt; tree fncall_param_front, fncall_param_rear; int map_ret; while (decl != NULL_TREE) { if ((mf_decl_eligible_p (decl) || TREE_CODE(TREE_TYPE(decl)) == ARRAY_TYPE) /* Not already processed. */ && ! mf_marked_p (decl) /* Automatic variable. */ && ! DECL_EXTERNAL (decl) && ! TREE_STATIC (decl) && get_name(decl)) { DEBUGLOG("DEBUG Instrumenting %s is_complete_type %d\n", IDENTIFIER_POINTER(DECL_NAME(decl)), COMPLETE_TYPE_P(decl)); /* construct a tree corresponding to the type struct{ unsigned int rz_front[6U]; original variable unsigned int rz_rear[6U]; }; */ if (!sframe_inserted){ gimple ensure_fn_call = gimple_build_call (lbc_ensure_sframe_bitmap_fndecl, 0); gimple_set_location (ensure_fn_call, location); gsi_insert_before (&initially_stmts, ensure_fn_call, GSI_SAME_STMT); sframe_inserted = true; } // Calculate the zone sizes size_t element_size = 0, request_size = 0; if (COMPLETE_TYPE_P(decl)){ request_size = TREE_INT_CST_LOW(TYPE_SIZE_UNIT(TREE_TYPE(decl))); if (TREE_CODE(TREE_TYPE(decl)) == ARRAY_TYPE) element_size = TREE_INT_CST_LOW(TYPE_SIZE_UNIT(TREE_TYPE(TREE_TYPE(decl)))); else element_size = request_size; } calculate_zone_sizes(element_size, request_size, /*global*/ false, COMPLETE_TYPE_P(decl), &front_rz_size, &rear_rz_size); DEBUGLOG("DEBUG *SIZES* req_size %u, ele_size %u, fsize %u, rsize %u\n", request_size, element_size, front_rz_size, rear_rz_size); tree struct_type = create_struct_type(decl, front_rz_size, rear_rz_size); tree struct_var = create_struct_var(struct_type, decl, location); declare_vars(struct_var, stmt, 0); /* Inserting into hashtable */ PWord_t PV; JSLI(PV, decl_map, mf_varname_tree(decl)); gcc_assert(PV); *PV = (PWord_t) struct_var; fsize = convert (unsigned_type_node, size_int(front_rz_size)); gcc_assert (is_gimple_val (fsize)); tree rz_front = TYPE_FIELDS(struct_type); fncall_param_front = mf_mark (build1 (ADDR_EXPR, ptr_type_node, build3 (COMPONENT_REF, TREE_TYPE(rz_front), struct_var, rz_front, NULL_TREE))); uninit_fncall_front = gimple_build_call (lbc_uninit_front_rz_fndecl, 2, fncall_param_front, fsize); init_fncall_front = gimple_build_call (lbc_init_front_rz_fndecl, 2, fncall_param_front, fsize); gimple_set_location (init_fncall_front, location); gimple_set_location (uninit_fncall_front, location); // In complete types have only a front red zone if (COMPLETE_TYPE_P(decl)){ rsize = convert (unsigned_type_node, size_int(rear_rz_size)); gcc_assert (is_gimple_val (rsize)); tree rz_rear = DECL_CHAIN(DECL_CHAIN(TYPE_FIELDS (struct_type))); fncall_param_rear = mf_mark (build1 (ADDR_EXPR, ptr_type_node, build3 (COMPONENT_REF, TREE_TYPE(rz_rear), struct_var, rz_rear, NULL_TREE))); init_fncall_rear = gimple_build_call (lbc_init_rear_rz_fndecl, 2, fncall_param_rear, rsize); uninit_fncall_rear = gimple_build_call (lbc_uninit_rear_rz_fndecl, 2, fncall_param_rear, rsize); gimple_set_location (init_fncall_rear, location); gimple_set_location (uninit_fncall_rear, location); } // TODO Do I need this? #if 0 if (DECL_INITIAL(decl) != NULL_TREE){ // This code never seems to be getting executed for somehting like int i = 10; // I have no idea why? But looking at the tree dump, seems like its because // by the time it gets here, these kind of statements are split into two statements // as int i; and i = 10; respectively. I am leaving it in just in case. tree orig_var_type = DECL_CHAIN(TYPE_FIELDS (struct_type)); tree orig_var_lval = mf_mark (build3 (COMPONENT_REF, TREE_TYPE(orig_var_type), struct_var, orig_var_type, NULL_TREE)); init_assign_stmt = gimple_build_assign(orig_var_lval, DECL_INITIAL(decl)); gimple_set_location (init_assign_stmt, location); } #endif if (gsi_end_p (initially_stmts)) { // TODO handle this if (!DECL_ARTIFICIAL (decl)) warning (OPT_Wmudflap, "mudflap cannot track %qE in stub function", DECL_NAME (decl)); } else { #if 0 // Insert the declaration initializer if (DECL_INITIAL(decl) != NULL_TREE) gsi_insert_before (&initially_stmts, init_assign_stmt, GSI_SAME_STMT); #endif //gsi_insert_before (&initially_stmts, register_fncall, GSI_SAME_STMT); gsi_insert_before (&initially_stmts, init_fncall_front, GSI_SAME_STMT); if (COMPLETE_TYPE_P(decl)) gsi_insert_before (&initially_stmts, init_fncall_rear, GSI_SAME_STMT); /* Accumulate the FINALLY piece. */ //gimple_seq_add_stmt (&finally_stmts, unregister_fncall); gimple_seq_add_stmt (&finally_stmts, uninit_fncall_front); if (COMPLETE_TYPE_P(decl)) gimple_seq_add_stmt (&finally_stmts, uninit_fncall_rear); } mf_mark (decl); } decl = DECL_CHAIN (decl); } /* Actually, (initially_stmts!=NULL) <=> (finally_stmts!=NULL) */ if (finally_stmts != NULL) { gimple stmt = gimple_build_try (seq, finally_stmts, GIMPLE_TRY_FINALLY); gimple_seq new_seq = gimple_seq_alloc (); gimple_seq_add_stmt (&new_seq, stmt); return new_seq; } else return seq; }
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 ; }