/** * Creates an expression wrapping an identifier */ struct memorycontainer* createIdentifierExpression(char * identifier) { struct memorycontainer* memoryContainer = (struct memorycontainer*) malloc(sizeof(struct memorycontainer)); if (doesVariableExist(identifier)) { memoryContainer->length=sizeof(unsigned char)+sizeof(unsigned short); memoryContainer->data=(char*) malloc(memoryContainer->length); memoryContainer->lineDefns=NULL; int location=appendStatement(memoryContainer, IDENTIFIER_TOKEN, 0); appendVariable(memoryContainer, getVariableId(identifier, 0), location); } else { memoryContainer->length=sizeof(unsigned char)+sizeof(unsigned short); memoryContainer->data=(char*) malloc(memoryContainer->length); appendStatement(memoryContainer, FN_ADDR_TOKEN, 0); struct lineDefinition * defn = (struct lineDefinition*) malloc(sizeof(struct lineDefinition)); defn->next=NULL; defn->type=4; defn->linenumber=line_num; defn->name=(char*) malloc(strlen(identifier)+1); strcpy(defn->name, identifier); defn->currentpoint=sizeof(unsigned char); memoryContainer->lineDefns=defn; if (currentCall==NULL) { mainCodeCallTree.calledFunctions[mainCodeCallTree.number_of_calls]=(char*)malloc(strlen(identifier)+1); strcpy(mainCodeCallTree.calledFunctions[mainCodeCallTree.number_of_calls++], identifier); } else { currentCall->calledFunctions[currentCall->number_of_calls]=(char*)malloc(strlen(identifier)+1); strcpy(currentCall->calledFunctions[currentCall->number_of_calls++], identifier); } } return memoryContainer; }
/** * Creates an expression from two other expressions with some operator (such as add, equality test etc...) */ static struct memorycontainer* createExpression(unsigned char token, struct memorycontainer* expression1, struct memorycontainer* expression2) { struct memorycontainer* memoryContainer = (struct memorycontainer*) malloc(sizeof(struct memorycontainer)); memoryContainer->length=expression1->length + expression2->length + sizeof(unsigned char); memoryContainer->data=(char*) malloc(memoryContainer->length); unsigned int location=0; location=appendStatement(memoryContainer, token, location); memcpy(&memoryContainer->data[location], expression1->data, expression1->length); location+=expression1->length; memcpy(&memoryContainer->data[location], expression2->data, expression2->length); memoryContainer->lineDefns=expression1->lineDefns; struct lineDefinition * root=memoryContainer->lineDefns, *r2; while (root != NULL) { root->currentpoint+=sizeof(unsigned char); root=root->next; } root=expression2->lineDefns; while (root != NULL) { root->currentpoint+=expression1->length+sizeof(unsigned char); r2=root->next; root->next=memoryContainer->lineDefns; memoryContainer->lineDefns=root; root=r2; } // Free up the expression 1 and expression 2 memory free(expression1->data); free(expression1); free(expression2->data); free(expression2); return memoryContainer; }
struct memorycontainer* createArrayExpression(struct stack_t* arrayVals, struct memorycontainer* repetitionExpr) { int lenOfArray=getStackSize(arrayVals); struct memorycontainer* expressionContainer=NULL; int i; for (i=0;i<lenOfArray;i++) { if (expressionContainer == NULL) { expressionContainer=getExpressionAt(arrayVals, i); } else { expressionContainer=concatenateMemory(expressionContainer, getExpressionAt(arrayVals, i)); } } struct memorycontainer* memoryContainer = (struct memorycontainer*) malloc(sizeof(struct memorycontainer)); memoryContainer->length=sizeof(unsigned char)*2 + sizeof(int); memoryContainer->data=(char*) malloc(memoryContainer->length); memoryContainer->lineDefns=NULL; int location=appendStatement(memoryContainer, ARRAY_TOKEN, 0); memcpy(&memoryContainer->data[location], &lenOfArray, sizeof(int)); location+=sizeof(int); unsigned char hasRepetitionExpr=repetitionExpr == NULL ? 0 : 1; memcpy(&memoryContainer->data[location], &hasRepetitionExpr, sizeof(unsigned char)); if (repetitionExpr != NULL) memoryContainer=concatenateMemory(memoryContainer, repetitionExpr); return concatenateMemory(memoryContainer, expressionContainer); }
/** * Appends and returns a stop statement */ struct memorycontainer* appendStopStatement() { struct memorycontainer* memoryContainer = (struct memorycontainer*) malloc(sizeof(struct memorycontainer)); memoryContainer->length=sizeof(unsigned char); memoryContainer->data=(char*) malloc(memoryContainer->length); memoryContainer->lineDefns=NULL; appendStatement(memoryContainer, STOP_TOKEN, 0); return memoryContainer; }
struct memorycontainer* createNoneExpression(void) { struct memorycontainer* memoryContainer = (struct memorycontainer*) malloc(sizeof(struct memorycontainer)); memoryContainer->length=sizeof(unsigned char); memoryContainer->data=(char*) malloc(memoryContainer->length); memoryContainer->lineDefns=NULL; appendStatement(memoryContainer, NONE_TOKEN, 0); return memoryContainer; }
void StartSubProgram( void ) { /****************************/ /* do some house cleaning before we start processing subprograms */ if( inSubPgm || SRU.sections ) { return; } if( SRU.var_sec == NULL && !(Options & OPT_GEN_C_CODE) ) { SRU.var_sec = appendStatement( VARIABLE_SECTION ); appendStatement( END_VARIABLE_SECTION ); } if( SRU.type_sec == NULL ) { SRU.type_sec = appendStatement( TYPE_PROTOTYPE_SECTION ); appendStatement( END_PROTOTYPE_SECTION ); } }
/** * Creates an expression wrapping a real number */ struct memorycontainer* createRealExpression(float number) { struct memorycontainer* memoryContainer = (struct memorycontainer*) malloc(sizeof(struct memorycontainer)); memoryContainer->length=sizeof(float) + sizeof(unsigned char); memoryContainer->data=(char*) malloc(memoryContainer->length); memoryContainer->lineDefns=NULL; int location=appendStatement(memoryContainer, REAL_TOKEN, 0); memcpy(&memoryContainer->data[location], &number, sizeof(float)); return memoryContainer; }
struct memorycontainer* createBooleanExpression(int booleanVal) { struct memorycontainer* memoryContainer = (struct memorycontainer*) malloc(sizeof(struct memorycontainer)); memoryContainer->length=sizeof(int) + sizeof(unsigned char); memoryContainer->data=(char*) malloc(memoryContainer->length); memoryContainer->lineDefns=NULL; int location=appendStatement(memoryContainer, BOOLEAN_TOKEN, 0); memcpy(&memoryContainer->data[location], &booleanVal, sizeof(int)); return memoryContainer; }
/** * Appends and returns a for iteration. This puts in the assignment of the initial value to the variable, the normal stuff and then * termination check at each iteration along with jumping to next iteration if applicable */ struct memorycontainer* appendForStatement(char * identifier, struct memorycontainer* exp, struct memorycontainer* block) { struct memorycontainer* initialLet=appendLetStatement("epy_i_ctr", createIntegerExpression(0)); struct memorycontainer* variantLet=appendLetStatement(identifier, createIntegerExpression(0)); struct memorycontainer* incrementLet=appendLetStatement("epy_i_ctr", createAddExpression(createIdentifierExpression("epy_i_ctr"), createIntegerExpression(1))); struct memorycontainer* memoryContainer = (struct memorycontainer*) malloc(sizeof(struct memorycontainer)); memoryContainer->length=sizeof(unsigned char)*2+sizeof(unsigned short) * 4 + exp->length + (block != NULL ? block->length : 0) + initialLet->length + variantLet->length + incrementLet->length; memoryContainer->data=(char*) malloc(memoryContainer->length); memoryContainer->lineDefns=NULL; struct memorycontainer* combinedBlock=block != NULL ? concatenateMemory(block, incrementLet) : incrementLet; unsigned int position=0; struct lineDefinition * defn = (struct lineDefinition*) malloc(sizeof(struct lineDefinition)); defn->next=memoryContainer->lineDefns; defn->type=0; defn->linenumber=currentForLine; defn->currentpoint=initialLet->length; memoryContainer->lineDefns=defn; position=appendMemory(memoryContainer, initialLet, position); position=appendMemory(memoryContainer, variantLet, position); position=appendStatement(memoryContainer, FOR_TOKEN, position); position=appendVariable(memoryContainer, getVariableId("epy_i_ctr", 0), position); position=appendVariable(memoryContainer, getVariableId(identifier, 0), position); position=appendMemory(memoryContainer, exp, position); unsigned short length=(unsigned short) combinedBlock->length; memcpy(&memoryContainer->data[position], &length, sizeof(unsigned short)); position+=sizeof(unsigned short); position=appendMemory(memoryContainer, combinedBlock, position); position=appendStatement(memoryContainer, GOTO_TOKEN, position); defn = (struct lineDefinition*) malloc(sizeof(struct lineDefinition)); defn->next=memoryContainer->lineDefns; defn->type=1; defn->linenumber=currentForLine; defn->currentpoint=position; memoryContainer->lineDefns=defn; currentForLine--; return memoryContainer; }
struct memorycontainer* appendReturnStatementWithExpression(struct memorycontainer* expressionContainer) { struct memorycontainer* memoryContainer = (struct memorycontainer*) malloc(sizeof(struct memorycontainer)); memoryContainer->length=sizeof(unsigned char)+expressionContainer->length; memoryContainer->data=(char*) malloc(memoryContainer->length); memoryContainer->lineDefns=NULL; unsigned int position=0; position=appendStatement(memoryContainer, RETURN_EXP_TOKEN, position); appendMemory(memoryContainer, expressionContainer, position); return memoryContainer; }
/** * @brief Removes the given variable definition/assignment statement. * * @param[in] stmt Statement to be removed. * @param[in] func If non-null and the removed statement is a variable definition * statement, updates the set of local variables of the function. * * @return A vector of statements (possibly empty) with which @a stmt has been * replaced. * * If there are function calls in the right-hand side of @a stmt, they are * preserved, and returned in the resulting list. Debug comments are also * preserved. * * Precondition: * - @a stmt is either a variable definition statement or an assign statement */ StmtVector removeVarDefOrAssignStatement(ShPtr<Statement> stmt, ShPtr<Function> func) { PRECONDITION(isVarDefOrAssignStmt(stmt), "the statement `" << stmt << "` is not a variable-defining or assign statement"); // A vector of statements with which stmt has been replaced. StmtVector newStmts; // Update also the set of local variables in func? if (auto varDefStmt = cast<VarDefStmt>(stmt)) { if (func) { func->removeLocalVar(varDefStmt->getVar()); } } // Is there a right-hand side? auto rhs = getRhs(stmt); if (!rhs) { // There is an empty initializer, so there are no function calls. Statement::removeStatementButKeepDebugComment(stmt); return newStmts; } // Are there any function calls in the right-hand side? auto calls = CallsObtainer::getCalls(rhs); if (calls.empty()) { // There are no function calls in the right-hand side. Statement::removeStatementButKeepDebugComment(stmt); return newStmts; } // // There are some function calls, so preserve them. // // Insert the first found call. auto callStmt = CallStmt::create(*calls.begin()); callStmt->setMetadata(stmt->getMetadata()); Statement::replaceStatement(stmt, callStmt); newStmts.push_back(callStmt); calls.erase(calls.begin()); // Insert the remaining calls. auto lastCallStmt = callStmt; for (auto call : calls) { callStmt = CallStmt::create(call); lastCallStmt->appendStatement(callStmt); newStmts.push_back(callStmt); lastCallStmt = callStmt; } return newStmts; }
/** * Appends and returns a conditional with else statement, a bit more complex as have to jump after the then block to the end of the * else block */ struct memorycontainer* appendIfElseStatement(struct memorycontainer* expressionContainer, struct memorycontainer* thenBlock, struct memorycontainer* elseBlock) { struct memorycontainer* memoryContainer = (struct memorycontainer*) malloc(sizeof(struct memorycontainer)); memoryContainer->length=sizeof(unsigned char)*2+sizeof(unsigned short)*2 + expressionContainer->length + (thenBlock != NULL ? thenBlock->length : 0) + (elseBlock != NULL ? elseBlock->length : 0); memoryContainer->data=(char*) malloc(memoryContainer->length); memoryContainer->lineDefns=NULL; unsigned int position=0; position=appendStatement(memoryContainer, IFELSE_TOKEN, position); position=appendMemory(memoryContainer, expressionContainer, position); unsigned short combinedThenGotoLength=(unsigned short) (thenBlock != NULL ? thenBlock->length : 0)+3; // add for goto and line num memcpy(&memoryContainer->data[position], &combinedThenGotoLength, sizeof(unsigned short)); position+=sizeof(unsigned short); if (thenBlock != NULL) { position=appendMemory(memoryContainer, thenBlock, position); } position=appendStatement(memoryContainer, GOTO_TOKEN, position); struct lineDefinition * defn = (struct lineDefinition*) malloc(sizeof(struct lineDefinition)); defn->next=memoryContainer->lineDefns; defn->type=1; defn->linenumber=currentForLine; defn->currentpoint=position; memoryContainer->lineDefns=defn; position+=sizeof(unsigned short); if (elseBlock != NULL) position=appendMemory(memoryContainer, elseBlock, position); defn = (struct lineDefinition*) malloc(sizeof(struct lineDefinition)); defn->next=memoryContainer->lineDefns; defn->type=0; defn->linenumber=currentForLine; defn->currentpoint=position; memoryContainer->lineDefns=defn; currentForLine--; return memoryContainer; }
static struct memorycontainer* appendLetIfNoAliasStatement(char * identifier, struct memorycontainer* expressionContainer) { struct memorycontainer* memoryContainer = (struct memorycontainer*) malloc(sizeof(struct memorycontainer)); memoryContainer->length=sizeof(unsigned char)+sizeof(unsigned short) + expressionContainer->length; memoryContainer->data=(char*) malloc(memoryContainer->length); memoryContainer->lineDefns=NULL; unsigned int position=0; position=appendStatement(memoryContainer, LETNOALIAS_TOKEN, position); position=appendVariable(memoryContainer, getVariableId(identifier, 1), position); appendMemory(memoryContainer, expressionContainer, position); return memoryContainer; }
/** * Appends in a do while statement, which assembles down to an if statement with jump at the end of the block * to retest the condition and either do another iteration or not */ struct memorycontainer* appendWhileStatement(struct memorycontainer* expression, struct memorycontainer* block) { struct memorycontainer* memoryContainer = (struct memorycontainer*) malloc(sizeof(struct memorycontainer)); memoryContainer->length=sizeof(unsigned char)+sizeof(unsigned short) * 3 + expression->length + (block != NULL ? block->length : 0); memoryContainer->data=(char*) malloc(memoryContainer->length); memoryContainer->lineDefns=NULL; unsigned int position=0; position=appendStatement(memoryContainer, IF_TOKEN, position); position=appendMemory(memoryContainer, expression, position); if (block != NULL) { unsigned short blockLen=(unsigned short) block->length + 4; memcpy(&memoryContainer->data[position], &blockLen, sizeof(unsigned short)); position+=sizeof(unsigned short); position=appendMemory(memoryContainer, block, position); } else { unsigned short blockLen=4; memcpy(&memoryContainer->data[position], &blockLen, sizeof(unsigned short)); position+=sizeof(unsigned short); } position=appendStatement(memoryContainer, GOTO_TOKEN, position); struct lineDefinition * defn = (struct lineDefinition*) malloc(sizeof(struct lineDefinition)); defn->next=memoryContainer->lineDefns; defn->type=0; defn->linenumber=currentForLine; defn->currentpoint=0; memoryContainer->lineDefns=defn; defn = (struct lineDefinition*) malloc(sizeof(struct lineDefinition)); defn->next=memoryContainer->lineDefns; defn->type=1; defn->linenumber=currentForLine; defn->currentpoint=position; memoryContainer->lineDefns=defn; currentForLine--; return memoryContainer; }
/** * Appends and returns a goto, this is added as a placeholder and then resolved at the end to point to the absolute byte code location * which is needed as we might be jumping forward and have not yet encountered the line label */ struct memorycontainer* appendGotoStatement(int lineNumber) { struct lineDefinition * defn = (struct lineDefinition*) malloc(sizeof(struct lineDefinition)); struct memorycontainer* memoryContainer = (struct memorycontainer*) malloc(sizeof(struct memorycontainer)); memoryContainer->length=sizeof(unsigned short)+sizeof(unsigned char); memoryContainer->data=(char*) malloc(memoryContainer->length); defn->next=NULL; defn->type=1; defn->linenumber=lineNumber; defn->currentpoint=sizeof(unsigned char); memoryContainer->lineDefns=defn; appendStatement(memoryContainer, GOTO_TOKEN, 0); return memoryContainer; }
static struct memorycontainer* createUnaryExpression(unsigned char token, struct memorycontainer* expression) { struct memorycontainer* memoryContainer = (struct memorycontainer*) malloc(sizeof(struct memorycontainer)); memoryContainer->length=expression->length + sizeof(unsigned char); memoryContainer->data=(char*) malloc(memoryContainer->length); unsigned int location=0; location=appendStatement(memoryContainer, token, location); memcpy(&memoryContainer->data[location], expression->data, expression->length); memoryContainer->lineDefns=expression->lineDefns; // Free up the expression memory free(expression->data); free(expression); return memoryContainer; }
/** * Appends and returns a conditional, this is without an else statement so sets that to be zero */ struct memorycontainer* appendIfStatement(struct memorycontainer* expressionContainer, struct memorycontainer* thenBlock) { struct memorycontainer* memoryContainer = (struct memorycontainer*) malloc(sizeof(struct memorycontainer)); memoryContainer->length=sizeof(unsigned char)+sizeof(unsigned short) + expressionContainer->length + (thenBlock != NULL ? thenBlock->length : 0); memoryContainer->data=(char*) malloc(memoryContainer->length); memoryContainer->lineDefns=NULL; unsigned int position=0; position=appendStatement(memoryContainer, IF_TOKEN, position); position=appendMemory(memoryContainer, expressionContainer, position); if (thenBlock != NULL) { unsigned short len=(unsigned short) thenBlock->length; memcpy(&memoryContainer->data[position], &len, sizeof(unsigned short)); position+=sizeof(unsigned short); position=appendMemory(memoryContainer, thenBlock, position); } else { unsigned short emptyLen=0; memcpy(&memoryContainer->data[position], &emptyLen, sizeof(unsigned short)); } return memoryContainer; }
/** * Creates an expression wrapping an identifier array access */ struct memorycontainer* createIdentifierArrayAccessExpression(char* identifier, struct stack_t* index_expressions) { int lenOfIndexes=getStackSize(index_expressions); struct memorycontainer* memoryContainer = (struct memorycontainer*) malloc(sizeof(struct memorycontainer)); memoryContainer->length=sizeof(unsigned short)+(sizeof(unsigned char)*2); memoryContainer->data=(char*) malloc(memoryContainer->length); memoryContainer->lineDefns=NULL; unsigned int position=0; position=appendStatement(memoryContainer, ARRAYACCESS_TOKEN, position); position=appendVariable(memoryContainer, getVariableId(identifier, 1), position); unsigned char packageNumDims=(unsigned char) lenOfIndexes; memcpy(&memoryContainer->data[position], &packageNumDims, sizeof(unsigned char)); position+=sizeof(unsigned char); int i; for (i=0;i<lenOfIndexes;i++) { memoryContainer=concatenateMemory(memoryContainer, getExpressionAt(index_expressions, i)); } return memoryContainer; }
/** * Appends and returns the setting of an array element (assignment) statement */ struct memorycontainer* appendArraySetStatement( char* identifier, struct stack_t* indexContainer, struct memorycontainer* expressionContainer) { struct memorycontainer* memoryContainer = (struct memorycontainer*) malloc(sizeof(struct memorycontainer)); memoryContainer->length=(sizeof(unsigned char)*2)+sizeof(unsigned short); memoryContainer->data=(char*) malloc(memoryContainer->length); memoryContainer->lineDefns=NULL; unsigned int position=0; position=appendStatement(memoryContainer, ARRAYSET_TOKEN, position); position=appendVariable(memoryContainer, getVariableId(identifier, 1), position); unsigned char numIndexes=(unsigned char) getStackSize(indexContainer); memcpy(&memoryContainer->data[position], &numIndexes, sizeof(unsigned char)); position+=sizeof(unsigned char); int i; for (i=0;i<numIndexes;i++) { memoryContainer=concatenateMemory(memoryContainer, getExpressionAt(indexContainer, i)); } memoryContainer=concatenateMemory(memoryContainer, expressionContainer); return memoryContainer; }
void MigrationOutliner::outline_ForToFunction(SgForStatement *f){ #define TOOL "OutlineFor_ToFunction" string msg; msg = "START: outline For loops"; DEBUG(TOOL,msg); //get parent function to create appropriate Name //append name to reflect position string addon = convertInt(counter); string outlineFuncName = "foorLOOP"; outlineFuncName +=addon; ++counter; //make parameterList SgFunctionParameterList *pList = new SgFunctionParameterList(); //make the func SgFunctionDeclaration *outlined = buildDefiningFunctionDeclaration(outlineFuncName, buildVoidType(), pList, f->get_scope()); //query for dependencies //make function declaration copy at top? //SgFunctionDeclaration* outlineFunc_Decl = buildNondefiningFunctionDeclaration(outlineFuncName, buildVoidType(), pList, f->get_scope()); //fill function with guts SgStatement* loop_body = f->get_loop_body(); //SgBasicBlock* lbody = loop_body->get_definition(); ROSE_ASSERT(loop_body != NULL); copyToFunctionBody(loop_body,outlined); appendStatement(outlined, f->get_scope()); //add dependencies to function parameters //insert funciton declaration in same file as where for loop originates //insert function definition at EOF }
static void resolveConstructor_Destructor( void ) { /*************************************************/ /* generate constructors and destructors if necessary */ char *buff; if( !( SRU.flags & CONSTRUCTOR_DEFINED ) ) { buff = alloca( sizeof(CONS_CALL_TEMPLATE) + strlen(SRU.con_name) + 1 ); appendStatement( ON_CONSTRUCTOR ); sprintf( buff, CONS_CALL_TEMPLATE, SRU.con_name ); appendStatement( buff ); appendStatement( END_ON ); } if( !( SRU.flags & DESTRUCTOR_DEFINED ) ) { buff = alloca( sizeof(DES_CALL_TEMPLATE) + strlen(SRU.des_name) + 1 ); appendStatement( ON_DESTRUCTOR ); sprintf( buff, DES_CALL_TEMPLATE, SRU.des_name ); appendStatement( buff ); appendStatement( END_ON ); } }
void ProcessStatement( void ) { /*****************************/ /* process an sru statement */ statement *stmt; statement *sc; var_rec *parm; /* create statement */ FinishLine(); stmt = appendStatement( GetParsedLine() ); stmt->typ = SRU.curr_typ; memcpy( &( stmt->data ), &( SRU.curr ), sizeof( spec ) ); /* depending on type, munge it */ switch( SRU.curr_typ ) { case( SRU_OTHER ): /* check for return statements in sru */ if( inSubPgm && ( SRU.flags & RETURN_STMT_PRESENT ) ) { SRU.subprog->data.sp.ret_stmt = stmt; SRU.flags &= ~RETURN_STMT_PRESENT; } break; case( SRU_SUBPROG ): /* make sure to add prototypes to apropriate section */ if( inSubPgm ) { break; } else if( !SRU.sections ) { inSubPgm = TRUE; } parm = stmt->data.sp.parm_list; while( parm != NULL ) { if( parm->fake ) { stmt->data.sp.fake = TRUE; /* only issue a warning for forward definitions so we don't * issue the same warning twice */ if( SRU.sections->data.sec.primary == ST_FORWARD ) { Warning( UNKNOWN_TYPE, parm->type.name, stmt->data.sp.name ); } break; } if( parm->array != NULL ) { if( parm->array->flags & ARRAY_MULTI_DIM ) { stmt->data.sp.fake = TRUE; if( SRU.sections->data.sec.primary == ST_FORWARD ) { Warning( ERR_MULTI_DIM_PARM, parm->name, stmt->data.sp.name ); } } else if( parm->array->flags & ARRAY_RANGE ) { stmt->data.sp.fake = TRUE; if( SRU.sections->data.sec.primary == ST_FORWARD ) { Warning( ERR_INDEX_DEF_PARM, parm->name, stmt->data.sp.name ); } } } parm = parm->next; } SRU.subprog = stmt; sc = SRU.sections; if( !inSubPgm && sc && ( sc->data.sec.secondary == ST_PROTOTYPES ) ) { if( sc->data.sec.primary == ST_FORWARD ) { stmt->link = SRU.forward_prots; SRU.forward_prots = stmt; } else if( sc->data.sec.primary == ST_TYPE ) { if( !(Options & OPT_GEN_C_CODE) && isConsDes(stmt->data.sp.name) ) { break; } InsertHashValue( SRU.type_prots, stmt->data.sp.name, strlen( stmt->data.sp.name ), stmt ); stmt->link = SRU.cpp_prots; SRU.cpp_prots = stmt; stmt->keep = TRUE; } } break; case( SRU_VARIABLE ): /* add global variables to appropriate section */ if( inSubPgm ) { break; } if( SRU.sections->data.sec.primary == ST_SHARED ) { stmt->link = SRU.shared_vars; SRU.shared_vars = stmt; } else { stmt->link = SRU.obj_vars; SRU.obj_vars = stmt; } stmt->keep = TRUE; break; case( SRU_SECTION ): /* identify two special sections when they come up */ if( inSubPgm ) { break; } stmt->link = SRU.sections; SRU.sections = stmt; if( stmt->data.sec.primary == ST_TYPE ) { if( stmt->data.sec.secondary == ST_PROTOTYPES ) { SRU.type_sec = stmt; } else if( stmt->data.sec.secondary == ST_VARIABLES ) { SRU.var_sec = stmt; } } break; default: assert( FALSE ); } memset( &( SRU.curr ), 0, sizeof( spec ) ); SRU.curr_typ = SRU_OTHER; }
/** * Appends and returns a call function, this is added as a placeholder and then resolved at the end to point to the absolute byte code location * which is needed as the function might appear at any point */ struct memorycontainer* appendCallFunctionStatement(char* functionName, struct stack_t* args) { char * last_dot=strrchr(functionName,'.'); if (last_dot != NULL) functionName=last_dot+1; if (currentFunctionName != NULL && strcmp(currentFunctionName, functionName) == 0) isFnRecursive=1; struct memorycontainer* assignmentContainer=NULL; unsigned short numArgs=(unsigned short) getStackSize(args); char *isArgIdentifier=(char*) malloc(numArgs); unsigned short *varIds=(unsigned short*) malloc(sizeof(unsigned short) * numArgs); char * varname=(char*) malloc(strlen(functionName)+5); int i; for (i=0;i<numArgs;i++) { struct memorycontainer* expression=getExpressionAt(args, i); unsigned char command=((unsigned char*) expression->data)[0]; if (command != IDENTIFIER_TOKEN) { isArgIdentifier[i]=0; sprintf(varname,"%s#%d", functionName, i); if (assignmentContainer == NULL) { assignmentContainer=appendLetStatement(varname, getExpressionAt(args, i)); } else { assignmentContainer=concatenateMemory(assignmentContainer, appendLetStatement(varname, getExpressionAt(args, i))); } } else { isArgIdentifier[i]=1; varIds[i]=*((unsigned short*) (&((char*) expression->data)[1])); free(expression->data); } } struct memorycontainer* memoryContainer = (struct memorycontainer*) malloc(sizeof(struct memorycontainer)); memoryContainer->length=sizeof(unsigned short)*(2+numArgs)+sizeof(unsigned char); memoryContainer->data=(char*) malloc(memoryContainer->length); unsigned int position=0; if (doesVariableExist(functionName)) { memoryContainer->lineDefns=NULL; position=appendStatement(memoryContainer, FNCALL_BY_VAR_TOKEN, position); position=appendVariable(memoryContainer, getVariableId(functionName, 0), position); } else { struct lineDefinition * defn = (struct lineDefinition*) malloc(sizeof(struct lineDefinition)); defn->next=NULL; defn->type=3; defn->linenumber=line_num; defn->name=(char*) malloc(strlen(functionName)+1); strcpy(defn->name, functionName); defn->currentpoint=sizeof(unsigned char); memoryContainer->lineDefns=defn; position=appendStatement(memoryContainer, FNCALL_TOKEN, position); position+=sizeof(unsigned short); } position=appendVariable(memoryContainer, numArgs, position); for (i=0;i<numArgs;i++) { if (isArgIdentifier[i]) { position=appendVariable(memoryContainer, varIds[i], position); } else { sprintf(varname,"%s#%d", functionName, i); position=appendVariable(memoryContainer, getVariableId(varname, 0), position); } } clearStack(args); free(varname); free(isArgIdentifier); free(varIds); if (currentCall==NULL) { mainCodeCallTree.calledFunctions[mainCodeCallTree.number_of_calls]=(char*)malloc(strlen(functionName)+1); strcpy(mainCodeCallTree.calledFunctions[mainCodeCallTree.number_of_calls++], functionName); } else { currentCall->calledFunctions[currentCall->number_of_calls]=(char*)malloc(strlen(functionName)+1); strcpy(currentCall->calledFunctions[currentCall->number_of_calls++], functionName); } if (assignmentContainer != NULL) { return concatenateMemory(assignmentContainer, memoryContainer); } else { return memoryContainer; } }
//! Translate generated Pragma Attributes one by one void translatePragmas (std::vector <MPI_PragmaAttribute*>& Attribute_List) { std::vector<MPI_PragmaAttribute*>::iterator iter; for (iter = Attribute_List.begin(); iter!=Attribute_List.end(); iter ++) { MPI_PragmaAttribute* cur_attr = *iter; cout<<"Translating ..." << cur_attr->toString() <<endl; SgScopeStatement* scope = cur_attr->pragma_node ->get_scope(); ROSE_ASSERT (scope != NULL); // simply obtain the default value and remove the pragma if (cur_attr-> pragma_type == pragma_mpi_device_default) { mpi_device_default_choice = cur_attr->default_semantics; // no automatic handling of attached preprocessed info. for now removeStatement(cur_attr->pragma_node, false); } // find omp target device(mpi:all) begin else if (cur_attr-> pragma_type == pragma_mpi_device_all_begin) { iter ++; // additional increment once MPI_PragmaAttribute* end_attribute = *iter; ROSE_ASSERT (end_attribute->pragma_type = pragma_mpi_device_all_end); removeStatement(cur_attr->pragma_node, false); removeStatement(end_attribute ->pragma_node, false); } else if (cur_attr-> pragma_type == pragma_mpi_device_master_begin) { // TODO refactor into a function iter ++; // additional increment once MPI_PragmaAttribute* end_attribute = *iter; ROSE_ASSERT (end_attribute->pragma_type = pragma_mpi_device_master_end); //insert a if (rank) .. after the end pragma SgIfStmt * ifstmt = buildIfStmt (buildEqualityOp(buildVarRefExp("_xomp_rank", scope), buildIntVal(0)), buildBasicBlock(), NULL); insertStatementAfter (end_attribute->pragma_node, ifstmt); SgBasicBlock * bb = isSgBasicBlock(ifstmt->get_true_body()); SgStatement* next_stmt = getNextStatement(cur_attr->pragma_node); // the next stmt is BB, skip it by starting the search from it ROSE_ASSERT (next_stmt != NULL); // normalize all declarations while ( next_stmt != end_attribute ->pragma_node) { // save current stmt before getting next one SgStatement* cur_stmt = next_stmt; next_stmt = getNextStatement (next_stmt); ROSE_ASSERT (next_stmt != NULL); if (SgVariableDeclaration* decl = isSgVariableDeclaration (cur_stmt)) splitVariableDeclaration (decl); } // move all non-declaration statements in between into the block next_stmt = getNextStatement(cur_attr->pragma_node); //reset from the beginning while ( next_stmt != end_attribute ->pragma_node) { // save current stmt before getting next one SgStatement* cur_stmt = next_stmt; next_stmt = getNextStatement (next_stmt); ROSE_ASSERT (next_stmt != NULL); if (!isSgVariableDeclaration(cur_stmt)) { // now remove the current stmt removeStatement (cur_stmt, false); appendStatement(cur_stmt, bb); } } // remove pragmas removeStatement(cur_attr->pragma_node, false); removeStatement(end_attribute ->pragma_node, false); } } // end for } // end translatePragmas ()
struct memorycontainer* appendNativeCallFunctionStatement(char* functionName, struct stack_t* args, struct memorycontainer* singleArg) { struct memorycontainer* memoryContainer = (struct memorycontainer*) malloc(sizeof(struct memorycontainer)); memoryContainer->length=(sizeof(unsigned char)*2) + sizeof(unsigned short); memoryContainer->data=(char*) malloc(memoryContainer->length); memoryContainer->lineDefns=NULL; unsigned int position=0; position=appendStatement(memoryContainer, NATIVE_TOKEN, position); if (strcmp(functionName, NATIVE_RTL_ISHOST_STR)==0) { position=appendStatement(memoryContainer, NATIVE_FN_RTL_ISHOST, position); } else if (strcmp(functionName, NATIVE_RTL_ISDEVICE_STR)==0) { position=appendStatement(memoryContainer, NATIVE_FN_RTL_ISDEVICE, position); } else if (strcmp(functionName, NATIVE_RTL_PRINT_STR)==0) { position=appendStatement(memoryContainer, NATIVE_FN_RTL_PRINT, position); } else if (strcmp(functionName, NATIVE_RTL_NUMDIMS_STR)==0) { position=appendStatement(memoryContainer, NATIVE_FN_RTL_NUMDIMS, position); } else if (strcmp(functionName, NATIVE_RTL_DSIZE_STR)==0) { position=appendStatement(memoryContainer, NATIVE_FN_RTL_DSIZE, position); } else if (strcmp(functionName, NATIVE_RTL_INPUT_STR)==0) { position=appendStatement(memoryContainer, NATIVE_FN_RTL_INPUT, position); } else if (strcmp(functionName, NATIVE_RTL_INPUTPRINT_STR)==0) { position=appendStatement(memoryContainer, NATIVE_FN_RTL_INPUTPRINT, position); } else if (strcmp(functionName, NATIVE_RTL_SYNC_STR)==0) { position=appendStatement(memoryContainer, NATIVE_FN_RTL_SYNC, position); } else if (strcmp(functionName, NATIVE_RTL_GC_STR)==0) { position=appendStatement(memoryContainer, NATIVE_FN_RTL_GC, position); } else if (strcmp(functionName, NATIVE_RTL_FREE_STR)==0) { position=appendStatement(memoryContainer, NATIVE_FN_RTL_FREE, position); } else if (strcmp(functionName, NATIVE_RTL_SEND_STR)==0) { position=appendStatement(memoryContainer, NATIVE_FN_RTL_SEND, position); } else if (strcmp(functionName, NATIVE_RTL_RECV_STR)==0) { position=appendStatement(memoryContainer, NATIVE_FN_RTL_RECV, position); } else if (strcmp(functionName, NATIVE_RTL_SENDRECV_STR)==0) { position=appendStatement(memoryContainer, NATIVE_FN_RTL_SENDRECV, position); } else if (strcmp(functionName, NATIVE_RTL_BCAST_STR)==0) { position=appendStatement(memoryContainer, NATIVE_FN_RTL_BCAST, position); } else if (strcmp(functionName, NATIVE_RTL_NUMCORES_STR)==0) { position=appendStatement(memoryContainer, NATIVE_FN_RTL_NUMCORES, position); } else if (strcmp(functionName, NATIVE_RTL_COREID_STR)==0) { position=appendStatement(memoryContainer, NATIVE_FN_RTL_COREID, position); } else if (strcmp(functionName, NATIVE_RTL_REDUCE_STR)==0) { position=appendStatement(memoryContainer, NATIVE_FN_RTL_REDUCE, position); } else if (strcmp(functionName, NATIVE_RTL_ALLOCATEARRAY_STR)==0) { position=appendStatement(memoryContainer, NATIVE_FN_RTL_ALLOCARRAY, position); } else if (strcmp(functionName, NATIVE_RTL_ALLOCATESHAREDARRAY_STR)==0) { position=appendStatement(memoryContainer, NATIVE_FN_RTL_ALLOCSHAREDARRAY, position); } else if (strcmp(functionName, NATIVE_RTL_MATH_STR)==0) { position=appendStatement(memoryContainer, NATIVE_FN_RTL_MATH, position); } else if (strcmp(functionName, NATIVE_RTL_PROBE_FOR_MESSAGE_STR)==0) { position=appendStatement(memoryContainer, NATIVE_FN_RTL_PROBE_FOR_MESSAGE, position); } else if (strcmp(functionName, NATIVE_RTL_TEST_FOR_SEND_STR)==0) { position=appendStatement(memoryContainer, NATIVE_FN_RTL_TEST_FOR_SEND, position); } else if (strcmp(functionName, NATIVE_RTL_WAIT_FOR_SEND_STR)==0) { position=appendStatement(memoryContainer, NATIVE_FN_RTL_WAIT_FOR_SEND, position); } else if (strcmp(functionName, NATIVE_RTL_SEND_NB_STR)==0) { position=appendStatement(memoryContainer, NATIVE_FN_RTL_SEND_NB, position); } else { fprintf(stderr, "Native function call of '%s' is not found\n", functionName); exit(EXIT_FAILURE); } unsigned short numArgs=args !=NULL ? (unsigned short) getStackSize(args) : singleArg != NULL ? 1 : 0; position=appendVariable(memoryContainer, numArgs, position); if (args != NULL) { int i; for (i=0;i<numArgs;i++) { struct memorycontainer* expression=getExpressionAt(args, i); memoryContainer=concatenateMemory(memoryContainer, expression); } } if (singleArg != NULL) memoryContainer=concatenateMemory(memoryContainer, singleArg); return memoryContainer; }
void CudaOutliner::functionParameterHandling(ASTtools::VarSymSet_t& syms, // regular (shared) parameters MintHostSymToDevInitMap_t hostToDevVars, const ASTtools::VarSymSet_t& pdSyms, // those must use pointer dereference const ASTtools::VarSymSet_t& pSyms, // private variables, handles dead variables (neither livein nor liveout) std::set<SgInitializedName*> & readOnlyVars, std::set<SgInitializedName*> & liveOutVars, SgFunctionDeclaration* func) // the outlined function { //ASTtools::VarSymSet_t syms; //std::copy(syms1.begin(), syms1.end(), std::inserter(syms,syms.begin())); VarSymRemap_t sym_remap; // variable remapping for regular(shared) variables VarSymRemap_t private_remap; // variable remapping for private/firstprivate/reduction variables ROSE_ASSERT (func); SgFunctionParameterList* params = func->get_parameterList (); ROSE_ASSERT (params); SgFunctionDefinition* def = func->get_definition (); ROSE_ASSERT (def); SgBasicBlock* body = def->get_body (); ROSE_ASSERT (body); // Place in which to put new outlined variable symbols. SgScopeStatement* args_scope = isSgScopeStatement (body); ROSE_ASSERT (args_scope); // For each variable symbol, create an equivalent function parameter. // Also create unpacking and repacking statements. int counter=0; // SgInitializedName* parameter1=NULL; // the wrapper parameter SgVariableDeclaration* local_var_decl = NULL; // handle OpenMP private variables/ or those which are neither live-in or live-out handlePrivateVariables(pSyms, body, private_remap); // -------------------------------------------------- // for each parameters passed to the outlined function // They include parameters for regular shared variables and // also the shared copies for firstprivate and reduction variables for (ASTtools::VarSymSet_t::reverse_iterator i = syms.rbegin ();i != syms.rend (); ++i) { // Basic information about the variable to be passed into the outlined function // Variable symbol name const SgInitializedName* i_name = (*i)->get_declaration (); ROSE_ASSERT (i_name); string name_str = i_name->get_name ().str (); SgName p_sg_name ( name_str); //SgType* i_type = i_name->get_type (); bool readOnly = false; if (readOnlyVars.find(const_cast<SgInitializedName*> (i_name)) != readOnlyVars.end()) readOnly = true; // step 1. Create parameters and insert it into the parameter list. // ---------------------------------------- SgInitializedName* p_init_name = NULL; SgVariableSymbol* host_sym= const_cast<SgVariableSymbol*> (*i); if(hostToDevVars.find(host_sym) != hostToDevVars.end() ){ //these are vector variables SgInitializedName* dev_name = hostToDevVars[host_sym]; p_init_name = createInitName (dev_name->get_name(), dev_name->get_type(), func, def); ROSE_ASSERT (p_init_name); prependArg(func->get_parameterList (),p_init_name); } else{ //scalar values p_init_name = createOneFunctionParameter(i_name, readOnly, func); } // step 2. Create unpacking/unwrapping statements, also record variables to be replaced // ---------------------------------------- // bool isPointerDeref = false; if (Outliner::enable_classic) { // classic methods use parameters directly, no unpacking is needed if (!readOnly) //read only variable should not have local variable declaration, using parameter directly // taking advantage of the same parameter names for readOnly variables // Let postprocessing to patch up symbols for them { // non-readonly variables need to be mapped to their parameters with different names (p__) // remapVarSyms() will use pointer dereferencing for all of them by default in C, // this is enough to mimic the classic outlining work //handleSharedVariables(*i, p_init_name, args_scope, sym_remap); //handleSharedVariables(*i, body, sym_remap); //Didem: I comment out this part because it uses pointer deferencing for all non-readonly variables. //recordSymRemap(*i,p_init_name, args_scope, sym_remap); } } else { local_var_decl = NULL; //createUnpackDecl (p_init_name, counter, isPointerDeref, i_name , NULL, body); ROSE_ASSERT (local_var_decl); prependStatement (local_var_decl,body); // regular and shared variables used the first local declaration recordSymRemap (*i, local_var_decl, args_scope, sym_remap); // transfer the value for firstprivate variables. } // step 3. Create and insert companion re-pack statement in the end of the function body // If necessary // ---------------------------------------- SgInitializedName* local_var_init = NULL; if (local_var_decl != NULL ) local_var_init = local_var_decl->get_decl_item (SgName (name_str.c_str ())); if (!SageInterface::is_Fortran_language() && !Outliner::enable_classic) ROSE_ASSERT(local_var_init!=NULL); SgExprStatement* pack_stmt = createPackStmt (local_var_init); if (pack_stmt) appendStatement (pack_stmt,body); counter ++; } //end for // variable substitution SgBasicBlock* func_body = func->get_definition()->get_body(); remapVarSyms (sym_remap, pdSyms, private_remap , func_body); }