BlockStmt* ForLoop::buildForLoop(Expr* indices, Expr* iteratorExpr, BlockStmt* body, bool coforall, bool zippered) { VarSymbol* index = newTemp("_indexOfInterest"); VarSymbol* iterator = newTemp("_iterator"); CallExpr* iterInit = 0; CallExpr* iterMove = 0; ForLoop* loop = new ForLoop(index, iterator, body, zippered); LabelSymbol* continueLabel = new LabelSymbol("_continueLabel"); LabelSymbol* breakLabel = new LabelSymbol("_breakLabel"); BlockStmt* retval = new BlockStmt(); iterator->addFlag(FLAG_EXPR_TEMP); // Unzippered loop, treat all objects (including tuples) the same if (zippered == false) iterInit = new CallExpr(PRIM_MOVE, iterator, new CallExpr("_getIterator", iteratorExpr)); // Expand tuple to a tuple containing appropriate iterators for each value. else iterInit = new CallExpr(PRIM_MOVE, iterator, new CallExpr("_getIteratorZip", iteratorExpr)); // try to optimize anonymous range iteration, replaces iterExpr in place optimizeAnonymousRangeIteration(iteratorExpr, zippered); index->addFlag(FLAG_INDEX_OF_INTEREST); iterMove = new CallExpr(PRIM_MOVE, index, new CallExpr("iteratorIndex", iterator)); if (indices == 0) indices = new UnresolvedSymExpr("chpl__elidedIdx"); checkIndices(indices); destructureIndices(loop, indices, new SymExpr(index), coforall); if (coforall) index->addFlag(FLAG_COFORALL_INDEX_VAR); loop->mContinueLabel = continueLabel; loop->mBreakLabel = breakLabel; loop->insertAtTail(new DefExpr(continueLabel)); retval->insertAtTail(new DefExpr(index)); retval->insertAtTail(new DefExpr(iterator)); retval->insertAtTail(iterInit); retval->insertAtTail(new BlockStmt(iterMove, BLOCK_TYPE)); retval->insertAtTail(loop); retval->insertAtTail(new DefExpr(breakLabel)); retval->insertAtTail(new CallExpr("_freeIterator", iterator)); return retval; }
BlockStmt* DoWhileStmt::build(Expr* cond, BlockStmt* body) { VarSymbol* condVar = newTemp(); CallExpr* condTest = new CallExpr("_cond_test", cond); LabelSymbol* continueLabel = new LabelSymbol("_continueLabel"); LabelSymbol* breakLabel = new LabelSymbol("_breakLabel"); DoWhileStmt* loop = 0; BlockStmt* retval = new BlockStmt(); // make variables declared in the scope of the body visible to // expressions in the condition of a do..while block if (body->length() == 1 && toBlockStmt(body->body.only())) { body = toBlockStmt(body->body.only()); body->remove(); } body->insertAtTail(new DefExpr(continueLabel)); body->insertAtTail(new CallExpr(PRIM_MOVE, condVar, condTest->copy())); loop = new DoWhileStmt(condVar, body); loop->mContinueLabel = continueLabel; loop->mBreakLabel = breakLabel; retval->insertAtTail(new DefExpr(condVar)); retval->insertAtTail(loop); retval->insertAtTail(new DefExpr(breakLabel)); return retval; }
SymbolTableEntry* Parser::parseExpressionPrime(SymbolTableEntry* prevEntry){ SymbolTableEntry* result = prevEntry; if(isNext(tc_RELOP)){ OpType t = m_currentToken->getOpType(); match(tc_RELOP); SymbolTableEntry* exp = parseSimpleExpression(); result = newTemp(); SymbolTableEntry* tr = newLabel(); SymbolTableEntry* end = newLabel(); if(t == op_LT){ m_code->generate(cd_LT, prevEntry, exp, tr); } else if(t == op_LE){ m_code->generate(cd_LE, prevEntry, exp, tr); } else if(t == op_GT){ m_code->generate(cd_GT, prevEntry, exp, tr); } else if(t == op_GE){ m_code->generate(cd_GE, prevEntry, exp, tr); } else if(t == op_EQ){ m_code->generate(cd_EQ, prevEntry, exp, tr); } else{ m_code->generate(cd_NE, prevEntry, exp, tr); } m_code->generate(cd_ASSIGN, m_symbolTable->lookup(CodeFalse), NULL, result); m_code->generate(cd_GOTO, NULL, NULL, end); m_code->generate(cd_LABEL, NULL, NULL, tr); m_code->generate(cd_ASSIGN, m_symbolTable->lookup(CodeTrue), NULL, result); m_code->generate(cd_LABEL, NULL, NULL, end); } return result; }
// tag iterators and replace delete statements with calls to ~chpl_destroy forv_Vec(CallExpr, call, gCallExprs) { if (call->isPrimitive(PRIM_YIELD)) { FnSymbol* fn = toFnSymbol(call->parentSymbol); // violations should have caused USR_FATAL in semanticChecks.cpp INT_ASSERT(fn && fn->hasFlag(FLAG_ITERATOR_FN)); } if (call->isPrimitive(PRIM_DELETE)) { SET_LINENO(call); VarSymbol* tmp = newTemp("delete_tmp"); call->insertBefore(new DefExpr(tmp)); call->insertBefore(new CallExpr(PRIM_MOVE, tmp, call->get(1)->remove())); call->insertBefore(new CallExpr("~chpl_destroy", gMethodToken, tmp)); CallExpr* freeExpr = callChplHereFree(tmp); if (fLocal) { call->insertBefore(freeExpr); } else { // // if compiling for multiple locales, we need to be sure that the // delete is executed on the locale on which the object lives for // correctness sake. // BlockStmt* onStmt = buildOnStmt(new SymExpr(tmp), freeExpr); call->insertBefore(onStmt); } call->remove(); } }
SymbolTableEntry* Parser::parseTermPrime(SymbolTableEntry* prevEntry){ if(isNext(tc_MULOP)){ OpType t = m_currentToken->getOpType(); match(tc_MULOP); SymbolTableEntry* factor = parseFactor(); SymbolTableEntry* temp = newTemp(); if(t == op_MULT){ m_code->generate(cd_MULT, prevEntry, factor, temp); } else if(t == op_DIVIDE){ m_code->generate(cd_DIVIDE, prevEntry, factor, temp); } else if(t == op_DIV){ m_code->generate(cd_DIV, prevEntry, factor, temp); } else if(t == op_MOD){ m_code->generate(cd_MOD, prevEntry, factor, temp); } else{ m_code->generate(cd_AND, prevEntry, factor, temp); } prevEntry = parseTermPrime(temp); } return prevEntry; }
TAC* binaryOp_tac(tacType_t type, TAC** children) { linkedList_t* temp1 = children[0]->destination; linkedList_t* temp2 = children[1]->destination; return append(append(children[0], children[1]), tac(type, newTemp(), temp1, temp2)); }
VarSymbol* ParamForLoop::newParamVar() { VarSymbol* retval = newTemp(); retval->addFlag(FLAG_MAYBE_PARAM); return retval; }
/* To implement task reduce intents, we follow the steps in propagateExtraLeaderArgs() and setupOneReduceIntent() I.e. add the following to the AST: * before 'call' def globalOp = new reduceType(origSym.type); * pass globalOp to call(); corresponding formal in 'fn': parentOp * inside 'fn' def currOp = parentOp.clone() def symReplace = currOp.identify; ... currOp.accumulate(symReplace); parentOp.combine(currOp); delete currOp; * after 'call' and its _waitEndCount() origSym = parentOp.generate(); delete parentOp; Put in a different way, a coforall like this: var x: int; coforall ITER with (OP reduce x) { BODY(x); // will typically include: x OP= something; } with its corresponding task-function representation: var x: int; proc coforall_fn() { BODY(x); } call coforall_fn(); is transformed into var x: int; var globalOp = new OP_SCAN_REDUCE_CLASS(x.type); proc coforall_fn(parentOp) { var currOp = parentOp.clone() var symReplace = currOp.identify; BODY(symReplace); currOp.accumulate(symReplace); parentOp.combine(currOp); delete currOp; } call coforall_fn(globalOp); // wait for endCount - not shown x = globalOp.generate(); delete globalOp; Todo: to support cobegin constructs, need to share 'globalOp' across all fn+call pairs for the same construct. */ static void addReduceIntentSupport(FnSymbol* fn, CallExpr* call, TypeSymbol* reduceType, Symbol* origSym, ArgSymbol*& newFormal, Symbol*& newActual, Symbol*& symReplace, bool isCoforall, Expr*& redRef1, Expr*& redRef2) { setupRedRefs(fn, true, redRef1, redRef2); VarSymbol* globalOp = new VarSymbol("reduceGlobal"); globalOp->addFlag(FLAG_NO_CAPTURE_FOR_TASKING); newActual = globalOp; VarSymbol* eltType = newTemp("redEltType"); eltType->addFlag(FLAG_MAYBE_TYPE); Expr* headAnchor = call; if (isCoforall) headAnchor = headAnchor->parentExpr; headAnchor->insertBefore(new DefExpr(eltType)); headAnchor->insertBefore("'move'(%S, 'typeof'(%S))", eltType, origSym); headAnchor->insertBefore(new DefExpr(globalOp)); AggregateType* reduceAt = toAggregateType(reduceType->type); INT_ASSERT(reduceAt); CallExpr* newOp = new CallExpr(reduceAt->defaultInitializer->name, new NamedExpr("eltType", new SymExpr(eltType))); headAnchor->insertBefore(new CallExpr(PRIM_MOVE, globalOp, newOp)); Expr* tailAnchor = findTailInsertionPoint(call, isCoforall); // Doing insertAfter() calls in reverse order. // Can't insertBefore() on tailAnchor->next - that can be NULL. tailAnchor->insertAfter("'delete'(%S)", globalOp); tailAnchor->insertAfter("'='(%S, generate(%S,%S))", origSym, gMethodToken, globalOp); ArgSymbol* parentOp = new ArgSymbol(INTENT_BLANK, "reduceParent", dtUnknown); newFormal = parentOp; VarSymbol* currOp = new VarSymbol("reduceCurr"); VarSymbol* svar = new VarSymbol(origSym->name, origSym->type); symReplace = svar; redRef1->insertBefore(new DefExpr(currOp)); redRef1->insertBefore("'move'(%S, clone(%S,%S))", // init currOp, gMethodToken, parentOp); redRef1->insertBefore(new DefExpr(svar)); redRef1->insertBefore("'move'(%S, identity(%S,%S))", // init svar, gMethodToken, currOp); redRef2->insertBefore(new CallExpr("accumulate", gMethodToken, currOp, svar)); redRef2->insertBefore(new CallExpr("chpl__reduceCombine", parentOp, currOp)); redRef2->insertBefore(new CallExpr("chpl__cleanupLocalOp", parentOp, currOp)); }
void TransformLogicalShortCircuit::exitCallExpr(CallExpr* call) { if (call->primitive == 0) { if (UnresolvedSymExpr* expr = toUnresolvedSymExpr(call->baseExpr)) { bool isLogicalAnd = strcmp(expr->unresolved, "&&") == 0; bool isLogicalOr = strcmp(expr->unresolved, "||") == 0; if (isLogicalAnd || isLogicalOr) { SET_LINENO(call); if (call->getStmtExpr() == mInsertionPoint) { Expr* left = call->get(1); Expr* right = call->get(2); VarSymbol* lvar = newTemp(); VarSymbol* eMsg = NULL; FnSymbol* ifFn = NULL; left->remove(); right->remove(); lvar->addFlag(FLAG_MAYBE_PARAM); if (isLogicalAnd) { eMsg = new_StringSymbol("cannot promote short-circuiting && operator"); ifFn = buildIfExpr(new CallExpr("isTrue", lvar), new CallExpr("isTrue", right), new SymExpr(gFalse)); } else { eMsg = new_StringSymbol("cannot promote short-circuiting || operator"); ifFn = buildIfExpr(new CallExpr("isTrue", lvar), new SymExpr(gTrue), new CallExpr("isTrue", right)); } ifFn->insertAtHead(new CondStmt(new CallExpr("_cond_invalid", lvar), new CallExpr("compilerError", eMsg))); ifFn->insertAtHead(new CallExpr(PRIM_MOVE, lvar, left)); ifFn->insertAtHead(new DefExpr(lvar)); call->baseExpr->replace(new UnresolvedSymExpr(ifFn->name)); mInsertionPoint->insertBefore(new DefExpr(ifFn)); } } } } }
void localizeGlobals() { if (fNoGlobalConstOpt) return; forv_Vec(FnSymbol, fn, gFnSymbols) { Map<Symbol*,VarSymbol*> globals; std::vector<BaseAST*> asts; collect_asts(fn->body, asts); for_vector(BaseAST, ast, asts) { if (SymExpr* se = toSymExpr(ast)) { Symbol* var = se->symbol(); ModuleSymbol* parentmod = toModuleSymbol(var->defPoint->parentSymbol); CallExpr* parentExpr = toCallExpr(se->parentExpr); bool inAddrOf = parentExpr && parentExpr->isPrimitive(PRIM_ADDR_OF); bool lhsOfMove = parentExpr && isMoveOrAssign(parentExpr) && (parentExpr->get(1) == se); // Is var a global constant? // Don't replace the var name in its init function since that's // where we're setting the value. Similarly, dont replace them // inside initStringLiterals // If the parentSymbol is the rootModule, the var is 'void,' // 'false,' '0,' ... // Also don't replace it when it's in an addr of primitive. if (parentmod && fn != parentmod->initFn && fn != initStringLiterals && !inAddrOf && !lhsOfMove && var->hasFlag(FLAG_CONST) && var->defPoint->parentSymbol != rootModule) { VarSymbol* local_global = globals.get(var); SET_LINENO(se); // Set the se line number for output if (!local_global) { const char * newname = astr("local_", var->cname); local_global = newTemp(newname, var->type); fn->insertAtHead(new CallExpr(PRIM_MOVE, local_global, var)); fn->insertAtHead(new DefExpr(local_global)); // Copy string immediates to localized strings so that // we can show the string value in comments next to uses. if (!llvmCodegen) if (VarSymbol* localVarSym = toVarSymbol(var)) if (Immediate* immediate = localVarSym->immediate) if (immediate->const_kind == CONST_KIND_STRING) local_global->immediate = new Immediate(immediate->v_string, immediate->string_kind); globals.put(var, local_global); } se->replace(new SymExpr(toSymbol(local_global))); } } } }
// // The argument expr is a use of a wide reference. Insert a check to ensure // that it is on the current locale, then drop its wideness by moving the // addr field into a non-wide of otherwise the same type. Then, replace its // use with the non-wide version. // static void insertLocalTemp(Expr* expr) { SymExpr* se = toSymExpr(expr); Expr* stmt = expr->getStmtExpr(); INT_ASSERT(se && stmt); SET_LINENO(se); VarSymbol* var = newTemp(astr("local_", se->var->name), se->var->type->getField("addr")->type); if (!fNoLocalChecks) { stmt->insertBefore(new CallExpr(PRIM_LOCAL_CHECK, se->copy())); } stmt->insertBefore(new DefExpr(var)); stmt->insertBefore(new CallExpr(PRIM_MOVE, var, se->copy())); se->replace(new SymExpr(var)); }
string AssignmentStatement::GenerateCode(){ stringstream varCode; ResultValue lvalue_r = lvalue->GenerateCode(); ResultValue rvalue_r = expr->GenerateCode(); LValueExpression* n = (LValueExpression*)lvalue; cout << " 1: " << lvalue_r.code << " 2: " << rvalue_r.code << endl; if (!ExistVarGlobal(n->variable_name) && !ExistVarTemp(n->variable_name)){ cout << "("<<line<<","<<column<<"): Variable \'" << n->variable_name << "\' no ha sido declarada."<<endl; } else if (lvalue_r.type == rvalue_r.type){ if (ExistVarGlobal(n->variable_name)){ if (rvalue_r.isConstant){ string p = newTemp(); varCode << rvalue_r.code; varCode << " li " << p << ", " << rvalue_r.value.int_value << endl; // VALIDAR los demas tipos (bool, string) varCode << " sw " << p << ", " << n->variable_name << endl; releaseTemp(p); } else { string p = newTemp(); varCode << rvalue_r.code; varCode << " sw " << rvalue_r.place << ", " << n->variable_name << endl; releaseTemp(p); } } if (ExistVarTemp(n->variable_name)){ if (rvalue_r.isConstant) varCode << " li " << varsTemp[n->variable_name].place << ", " << rvalue_r.value.int_value << endl; else varCode << " move " << varsTemp[n->variable_name].place << ", " << rvalue_r.place << endl; } } else cout << " ERROR en Statement ("<<line<<","<<column<<"): Variable \'"<< n->variable_name << "\' No se puede convertir \'" << TypeToString(rvalue_r.type) << "\' a \'" << TypeToString(lvalue_r.type) << "\'"<<endl; return varCode.str(); }
SymbolTableEntry* Parser::parseSimpleExpression(){ int sign = false; if(isNext(tc_ADDOP)){ if(m_currentToken->getOpType() == op_MINUS){ sign = true; } parseSign(); } SymbolTableEntry* entry = parseTerm(); entry = parseSimpleExpressionPrime(entry); SymbolTableEntry* result = entry; if(sign){ result = newTemp(); m_code->generate(cd_UMINUS, entry, NULL, result); } return result; }
forv_Vec(CallExpr, call, gCallExprs) { if (call->isPrimitive(PRIM_CHECK_ERROR)) { SET_LINENO(call); SymExpr* errSe = toSymExpr(call->get(1)); Symbol* errorVar= errSe->symbol(); VarSymbol* errorExistsVar = newTemp("errorExists", dtBool); DefExpr* def = new DefExpr(errorExistsVar); CallExpr* errorExists = new CallExpr(PRIM_NOTEQUAL, errorVar, gNil); CallExpr* move = new CallExpr(PRIM_MOVE, errorExistsVar, errorExists); Expr* stmt = call->getStmtExpr(); stmt->insertBefore(def); def->insertAfter(move); call->replace(new SymExpr(errorExistsVar)); } }
SymbolTableEntry* Parser::parseSimpleExpressionPrime(SymbolTableEntry* prevEntry){ SymbolTableEntry* temp = prevEntry; if(isNext(tc_ADDOP)){ OpType t = m_currentToken->getOpType(); match(tc_ADDOP); temp = newTemp(); SymbolTableEntry* term = parseTerm(); if(t == op_PLUS){ m_code->generate(cd_ADD, prevEntry, term, temp); } else if(t == op_MINUS){ m_code->generate(cd_SUB, prevEntry, term, temp); } else{ m_code->generate(cd_OR, prevEntry, term, temp); } prevEntry = parseSimpleExpressionPrime(temp); } return temp; }
void localizeGlobals() { if (fNoGlobalConstOpt) return; forv_Vec(FnSymbol, fn, gFnSymbols) { Map<Symbol*,VarSymbol*> globals; std::vector<BaseAST*> asts; collect_asts(fn->body, asts); for_vector(BaseAST, ast, asts) { if (SymExpr* se = toSymExpr(ast)) { Symbol* var = se->var; ModuleSymbol* parentmod = toModuleSymbol(var->defPoint->parentSymbol); CallExpr* parentExpr = toCallExpr(se->parentExpr); bool inAddrOf = parentExpr && parentExpr->isPrimitive(PRIM_ADDR_OF); // Is var a global constant? // Don't replace the var name in its init function since that's // where we're setting the value. Similarly, dont replace them // inside initStringLiterals // If the parentSymbol is the rootModule, the var is 'void,' // 'false,' '0,' ... // Also don't replace it when it's in an addr of primitive. if (parentmod && fn != parentmod->initFn && fn != initStringLiterals && !inAddrOf && var->hasFlag(FLAG_CONST) && var->defPoint->parentSymbol != rootModule) { VarSymbol* local_global = globals.get(var); SET_LINENO(se); // Set the se line number for output if (!local_global) { const char * newname = astr("local_", var->cname); local_global = newTemp(newname, var->type); fn->insertAtHead(new CallExpr(PRIM_MOVE, local_global, var)); fn->insertAtHead(new DefExpr(local_global)); globals.put(var, local_global); } se->replace(new SymExpr(toSymbol(local_global))); } } } }
SymbolTableEntry* Parser::parseFactor(){ SymbolTableEntry* factor = NULL; SymbolTableEntry* result = m_symbolTable->lookup(CodeFalse); if(isNext(tc_ID)){ factor = m_currentToken->getSymTabEntry(); match(tc_ID); result = parseFactorPrime(factor); } else if(isNext(tc_LPAREN)){ match(tc_LPAREN); result = parseExpression(); match(tc_RPAREN); if(m_parserError){ TokenCode synch[] = {tc_RPAREN, tc_END, tc_ADDOP, tc_MULOP, tc_RELOP, tc_THEN, tc_DO, tc_COMMA, tc_RBRACKET, tc_SEMICOL, tc_ELSE, tc_NONE}; recover(synch); // if(isNext(tc_RPAREN)){ // match(tc_RPAREN); // } } } else if(isNext(tc_NOT)){ match(tc_NOT); factor = parseFactor(); result = newTemp(); m_code->generate(cd_NOT, factor, NULL, result); } else{ result = m_currentToken->getSymTabEntry(); match(tc_NUMBER); if(m_parserError){ TokenCode synch[] = {tc_RPAREN, tc_END, tc_ADDOP, tc_MULOP, tc_RELOP, tc_THEN, tc_DO, tc_COMMA, tc_RBRACKET, tc_SEMICOL, tc_ELSE, tc_NONE}; recover(synch); // if(isNext(tc_NUMBER)){ // match(tc_NUMBER); // } } } return result; }
//进行规约的操作 bool LRGramar::doGuiYue(const int ruleNum) { switch(ruleNum) { case R1: //执行进出站等相关操作 if(!doRules(A_NTERMINAL,4)) { return false; } break; case R2: if(!doRules(B_NTERMINAL,3)) { return false; } break; case R3: if(!doRules(C_NTERMINAL,3)) { return false; } break; case R4: if(!doRules(C_NTERMINAL,0)) { return false; } break; case R5: if(!doRules(D_NTERMINAL,1)) { return false; } break; case R6: case R7: if(!doRules(D_NTERMINAL,1)) { return false; } else { } break; case R8: if(!doRules(F_NTERMINAL,3)) { return false; } else { //堆栈是先进先出 int argP = variableBufferPtr--; int resultPtr = variableBufferPtr--; emit("=",variableBuffer[argP]," ",variableBuffer[resultPtr]); } break; case R9: if(!doRules(G_NTERMINAL,2)) { return false; } else { backPatch(trueChainHead,nextq); //回填真链头 } break; case R10: if(!doRules(S_NTERMINAL,2)) { return false; } else { backPatch(falseChain[falseChainPtr--],nextq); } break; case R11: if(!doRules(T_NTERMINAL,3)) { return false; } else { emit("goto","","","0"); backPatch(falseChain[falseChainPtr--],nextq); falseChain[++falseChainPtr] = nextq-1; } break; case R12: if(!doRules(S_NTERMINAL,2)) { return false; } backPatch(falseChain[falseChainPtr--],nextq); break; case R13: if(!doRules(W_NTERMINAL,2)) { return false; } else { backPatch(trueChainHead,doTrue[doTruePtr--]); backPatch(falseChain[falseChainPtr--],nextq); } break; case R14: if(!doRules(K_NTERMINAL,1)) { return false; } doTrue[++doTruePtr] = nextq;//保存do后面的地址 break; case R15: if(!doRules(L_NTERMINAL,2)) { return false; } break; case R16: if(!doRules(N_NTERMINAL,2)) { return false; } break; case R17: if(!doRules(Q_NTERMINAL,3)) { return false; } else { trueChainHead = nextq; falseChain[++falseChainPtr]=nextq+1; char temp[10]; int arg2 = variableBufferPtr--; int arg1 = variableBufferPtr--; sprintf(temp,"%s%s%s",variableBuffer[arg1],lastOp[OpPtr--],variableBuffer[arg2]); emit("if",temp,"goto","0"); emit("goto","","","0"); } break; case R18: if(!doRules(P_NTERMINAL,2)) { return false; } else { if(strcmp(variableBuffer[variableBufferPtr],"null")!=0) { char *pPlace = newTemp(); emit(lastOp[OpPtr--],variableBuffer[variableBufferPtr--],variableBuffer[variableBufferPtr--],pPlace); strcpy(variableBuffer[++variableBufferPtr],pPlace); } else { variableBufferPtr--; } } break; case R19: if(!doRules(H_NTERMINAL,3)) { return false; } else { if(strcmp(variableBuffer[variableBufferPtr],"null")!=0) { char *hPlace = newTemp(); emit(lastOp[OpPtr--],variableBuffer[variableBufferPtr--],variableBuffer[variableBufferPtr--],hPlace); strcpy(variableBuffer[++variableBufferPtr],hPlace); } else { variableBufferPtr--; } strcpy(lastOp[++OpPtr],"+"); } break; case R20: if(!doRules(H_NTERMINAL,3)) { return false; } else { if(strcmp(variableBuffer[variableBufferPtr],"null")!=0) { char *hPlace = newTemp(); emit(lastOp[OpPtr--],variableBuffer[variableBufferPtr--],variableBuffer[variableBufferPtr--],hPlace); strcpy(variableBuffer[++variableBufferPtr],hPlace); } else { variableBufferPtr--; } strcpy(lastOp[++OpPtr],"-"); } break; case R21: if(!doRules(H_NTERMINAL,0)) { return false; } else { strcpy(variableBuffer[++variableBufferPtr],"null"); } break; case R22: if(!doRules(Z_NTERMINAL,2)) { return false; } else { if(strcmp(variableBuffer[variableBufferPtr],"null")!=0) { char *zPlace = newTemp(); emit(lastOp[OpPtr--],variableBuffer[variableBufferPtr--],variableBuffer[variableBufferPtr--],zPlace); strcpy(variableBuffer[++variableBufferPtr],zPlace); } else { variableBufferPtr--; } } break; case R23: if(!doRules(V_NTERMINAL,3)) { return false; } else { if(strcmp(variableBuffer[variableBufferPtr],"null")!=0) { char *vPlace = newTemp(); emit(lastOp[--OpPtr],variableBuffer[variableBufferPtr--],variableBuffer[variableBufferPtr--],vPlace); strcpy(variableBuffer[++variableBufferPtr],vPlace); } else { variableBufferPtr--; } strcpy(lastOp[++OpPtr] ,"*"); } break; case R24: if(!doRules(V_NTERMINAL,3)) { return false; } else { if(strcmp(variableBuffer[variableBufferPtr],"null")!=0) { char *vPlace = newTemp(); emit(lastOp[--OpPtr],variableBuffer[variableBufferPtr--],variableBuffer[variableBufferPtr--],vPlace); strcpy(variableBuffer[++variableBufferPtr],vPlace); } else { variableBufferPtr--; } strcpy(lastOp[++OpPtr] ,"/"); } break; case R25: case R26: if(!doRules(U_NTERMINAL,1)) { return false; } break; case R27: if(!doRules(U_NTERMINAL,3)) { return false; } break; case R28: strcpy(lastOp[++OpPtr],"<"); if(!doRules(Y_NTERMINAL,1)) { return false; } break; case R29: if(!doRules(Y_NTERMINAL,1)) { return false; } strcpy(lastOp[++OpPtr],"<="); break; case R30: if(!doRules(Y_NTERMINAL,1)) { return false; } strcpy(lastOp[++OpPtr],">"); break; case R31: if(!doRules(Y_NTERMINAL,1)) { return false; } strcpy(lastOp[++OpPtr],">="); break; case R32: if(!doRules(Y_NTERMINAL,1)) { return false; } strcpy(lastOp[++OpPtr],"=="); break; case R33: if(!doRules(Y_NTERMINAL,1)) { return false; } strcpy(lastOp[++OpPtr],"!="); break; case R34: if(!doRules(V_NTERMINAL,0)) { return false; } else { strcpy(variableBuffer[++variableBufferPtr],"null"); } break; default: return false; } return true; }
// // If call has the potential to cause communication, assert that the wide // reference that might cause communication is local and remove its wide-ness // // The organization of this function follows the order of CallExpr::codegen() // leaving out primitives that don't communicate. // static void localizeCall(CallExpr* call) { if (call->primitive) { switch (call->primitive->tag) { case PRIM_ARRAY_SET: /* Fallthru */ case PRIM_ARRAY_SET_FIRST: if (call->get(1)->typeInfo()->symbol->hasFlag(FLAG_WIDE_CLASS)) { insertLocalTemp(call->get(1)); } break; case PRIM_MOVE: case PRIM_ASSIGN: // Not sure about this one. if (CallExpr* rhs = toCallExpr(call->get(2))) { if (rhs->isPrimitive(PRIM_DEREF)) { if (rhs->get(1)->typeInfo()->symbol->hasFlag(FLAG_WIDE_REF) || rhs->get(1)->typeInfo()->symbol->hasFlag(FLAG_WIDE_CLASS)) { insertLocalTemp(rhs->get(1)); if (!rhs->get(1)->typeInfo()->symbol->hasFlag(FLAG_REF)) { INT_ASSERT(rhs->get(1)->typeInfo() == dtString); // special handling for wide strings rhs->replace(rhs->get(1)->remove()); } } break; } else if (rhs->isPrimitive(PRIM_GET_MEMBER) || rhs->isPrimitive(PRIM_GET_SVEC_MEMBER) || rhs->isPrimitive(PRIM_GET_MEMBER_VALUE) || rhs->isPrimitive(PRIM_GET_SVEC_MEMBER_VALUE)) { if (rhs->get(1)->typeInfo()->symbol->hasFlag(FLAG_WIDE_REF) || rhs->get(1)->typeInfo()->symbol->hasFlag(FLAG_WIDE_CLASS)) { SymExpr* sym = toSymExpr(rhs->get(2)); INT_ASSERT(sym); if (!sym->var->hasFlag(FLAG_SUPER_CLASS)) { insertLocalTemp(rhs->get(1)); } } break; } else if (rhs->isPrimitive(PRIM_ARRAY_GET) || rhs->isPrimitive(PRIM_ARRAY_GET_VALUE)) { if (rhs->get(1)->typeInfo()->symbol->hasFlag(FLAG_WIDE_CLASS)) { SymExpr* lhs = toSymExpr(call->get(1)); Expr* stmt = call->getStmtExpr(); INT_ASSERT(lhs && stmt); SET_LINENO(stmt); insertLocalTemp(rhs->get(1)); VarSymbol* localVar = NULL; if (rhs->isPrimitive(PRIM_ARRAY_GET)) localVar = newTemp(astr("local_", lhs->var->name), lhs->var->type->getField("addr")->type); else localVar = newTemp(astr("local_", lhs->var->name), lhs->var->type); stmt->insertBefore(new DefExpr(localVar)); lhs->replace(new SymExpr(localVar)); stmt->insertAfter(new CallExpr(PRIM_MOVE, lhs, new SymExpr(localVar))); } break; } else if (rhs->isPrimitive(PRIM_GET_UNION_ID)) { if (rhs->get(1)->typeInfo()->symbol->hasFlag(FLAG_WIDE_REF)) { insertLocalTemp(rhs->get(1)); } break; } else if (rhs->isPrimitive(PRIM_TESTCID) || rhs->isPrimitive(PRIM_GETCID)) { if (rhs->get(1)->typeInfo()->symbol->hasFlag(FLAG_WIDE_CLASS)) { insertLocalTemp(rhs->get(1)); } break; } ; } if (call->get(1)->typeInfo()->symbol->hasFlag(FLAG_WIDE_CLASS) && !call->get(2)->typeInfo()->symbol->hasFlag(FLAG_WIDE_CLASS)) { break; } if (call->get(1)->typeInfo()->symbol->hasFlag(FLAG_WIDE_REF) && !call->get(2)->typeInfo()->symbol->hasFlag(FLAG_WIDE_REF) && !call->get(2)->typeInfo()->symbol->hasFlag(FLAG_REF)) { insertLocalTemp(call->get(1)); } break; case PRIM_DYNAMIC_CAST: if (call->get(2)->typeInfo()->symbol->hasFlag(FLAG_WIDE_CLASS)) { insertLocalTemp(call->get(2)); if (call->get(1)->typeInfo()->symbol->hasFlag(FLAG_WIDE_CLASS) || call->get(1)->typeInfo()->symbol->hasFlag(FLAG_WIDE_REF)) { toSymExpr(call->get(1))->var->type = call->get(1)->typeInfo()->getField("addr")->type; } } break; case PRIM_SETCID: if (call->get(1)->typeInfo()->symbol->hasFlag(FLAG_WIDE_CLASS)) { insertLocalTemp(call->get(1)); } break; case PRIM_SET_UNION_ID: if (call->get(1)->typeInfo()->symbol->hasFlag(FLAG_WIDE_REF)) { insertLocalTemp(call->get(1)); } break; case PRIM_SET_MEMBER: case PRIM_SET_SVEC_MEMBER: if (call->get(1)->typeInfo()->symbol->hasFlag(FLAG_WIDE_CLASS) || call->get(1)->typeInfo()->symbol->hasFlag(FLAG_WIDE_REF)) { insertLocalTemp(call->get(1)); } break; default: break; } } }
static IRTemp for_sg__newIRTemp_cb ( IRType ty, void* opaque ) { PCEnv* pce = (PCEnv*)opaque; return newTemp( pce, ty, NonShad ); }
// 表达式 string CodeGenerator::Expr() { if(Tokens[CurToken].Type == String) { string res = newTemp("string"); newConst("string", Tokens[CurToken].value); CurToken++; return res; } int L = CurToken, R; int cntBrac = 0; for(R = L; R < Tokens.size(); R++) { string val = Tokens[R].value; if(val == ";" || val == ")" && cntBrac == 0) break; if(val == "(") cntBrac++; if(val == ")") cntBrac--; } CurToken = R; map<string, int> Prior; Prior["("] = 10, Prior[")"] = 0; Prior["!"] = 1; Prior["%"] = Prior["*"] = Prior["/"] = 2; Prior["+"] = Prior["-"] = 3; Prior[">="] = Prior["<="] = Prior[">"] = Prior["<"] = 4; Prior["=="] = Prior["!="] = 5; Prior["&&"] = 6; Prior["||"] = 7; stack<string> Num, Op; for(int i = L; i < R; i++) { string Type = CodeToString(Tokens[i]); string val = Tokens[i].value; if(Type == "number" || Type == "id") { if(Type == "id") Num.push(val); else Num.push(newConst((string)(Tokens[i].Type == Integer ? "int" : "double"), itos(Tokens[i].num))); } else { if(val == "(") { Op.push(val); } else if(val == ")") { while(Op.top() != "(") { string op = Op.top(); Op.pop(); string y = Num.top(); Num.pop(); if(op == "!") { string res = newTemp(VarTable[y].Type); Num.push(res); addQuad(op, y, "$", res); continue; } string x = Num.top(); Num.pop(); string res = newTemp(VarTable[x].Type); Num.push(res); if(op == ">=" || op == "<=" || op == "==" || op == "!=" || op == ">" || op == "<") { addQuad("J" + op, x, y, itos(CurLabel + 3)); addQuad("=", res, "0", res); addQuad("J", "$", "$", itos(CurLabel + 2)); addQuad("=", res, "1", res); } else { addQuad(op, x, y, res); } } Op.pop(); } else { while(!Op.empty() && Prior[val] >= Prior[Op.top()]) { string op = Op.top(); Op.pop(); string y = Num.top(); Num.pop(); if(op == "!") { string res = newTemp(VarTable[y].Type); Num.push(res); addQuad(op, y, "$", res); continue; } string x = Num.top(); Num.pop(); string res = newTemp(VarTable[x].Type); Num.push(res); if(op == ">=" || op == "<=" || op == "==" || op == "!=" || op == ">" || op == "<") { addQuad("J" + op, x, y, itos(CurLabel + 3)); addQuad("=", res, "0", res); addQuad("J", "$", "$", itos(CurLabel + 2)); addQuad("=", res, "1", res); } else { addQuad(op, x, y, res); } } Op.push(val); } } } while(!Op.empty()) { string op = Op.top(); Op.pop(); string y = Num.top(); Num.pop(); if(op == "!") { string res = newTemp(VarTable[y].Type); Num.push(res); addQuad(op, y, "$", res); continue; } string x = Num.top(); Num.pop(); string res = newTemp(VarTable[x].Type); Num.push(res); if(op == ">=" || op == "<=" || op == "==" || op == "!=" || op == ">" || op == "<") { addQuad("J" + op, x, y, itos(CurLabel + 3)); addQuad("=", res, "0", res); addQuad("J", "$", "$", itos(CurLabel + 2)); addQuad("=", res, "1", res); } else { addQuad(op, x, y, res); } } return Num.top(); }
TAC* unaryOp_tac(tacType_t type, TAC* op) { return append(op, tac(type, newTemp(), op->destination, NULL)); }
TAC* call_tac(TAC* funcId, TAC* args) { return append(append(args, funcId), tac(TAC_CALL, newTemp(), funcId->destination, NULL)); }
TAC* pointer_declaration_tac(TAC* id, TAC* literal) { linkedList_t* temp = newTemp(); return tac(TAC_MOVE_I,temp,literal->destination,NULL); }
TAC* generateCode(AST* ast) { if(ast == NULL) return NULL; TAC* childTac[4]; childTac[0] = generateCode(ast->child[0]); childTac[1] = generateCode(ast->child[1]); childTac[2] = generateCode(ast->child[2]); childTac[3] = generateCode(ast->child[3]); TAC* result; switch(ast->node_type) { case LITERAL: result = tac(TAC_SYMBOL, ast->node, NULL, NULL); break; case IDENTIFIER: result = tac(TAC_SYMBOL, ast->node, NULL, NULL); break; case ADDITION: result = binaryOp_tac(TAC_ADD, childTac); break; case SUBTRACTION: result = binaryOp_tac(TAC_SUB, childTac); break; case MULTIPLICATION: result = binaryOp_tac(TAC_MUL, childTac); break; case DIVISION: result = binaryOp_tac(TAC_DIV, childTac); break; case LESSERTHAN: result = binaryOp_tac(TAC_LESS, childTac); break; case GREATERTHAN: result = binaryOp_tac(TAC_GREATER, childTac); break; case LESSEREQUAL: result = binaryOp_tac(TAC_LESS_EQUAL, childTac); break; case GREATEREQUAL: result = binaryOp_tac(TAC_GREATER_EQUAL, childTac); break; case EQUAL: result = binaryOp_tac(TAC_EQUAL, childTac); break; case NOTEQUAL: result = binaryOp_tac(TAC_NOT_EQUAL, childTac); break; case AND: result = binaryOp_tac(TAC_AND, childTac); break; case OR: result = binaryOp_tac(TAC_OR, childTac); break; case REF: result = tac(TAC_REF, newTemp(), childTac[0]->destination, NULL); break; case DEREF: result = tac(TAC_DEREF, newTemp(), childTac[0]->destination, NULL); break; case IFTHEN: case IFTHENELSE: result = ifZero_tac(childTac[0], childTac[1], childTac[2]); break; case LOOP: result = loop_tac(childTac[0], childTac[1]); break; case ARRAYACCESS: result = tac(TAC_ARRAYACCESS, childTac[0]->destination, childTac[1]->destination, NULL); break; case ASSIGNMENT: result = assignment_tac(childTac[0], childTac[1]); break; case FUNCTIONCALL: result = call_tac(childTac[0], childTac[1]); break; case ARGUMENTLIST: result = args_tac(childTac); break; case ELEMENTLIST: result = output_args_tac(childTac); break; case RETURN: result = return_tac(childTac[0]); break; case DECLARATION: result = declaration_tac(childTac[1], childTac[2]); break; case ARRAYDECLARATION: result = array_declaration_tac(childTac[1], ast->child[3]); break; case POINTERDECLARATION: result = pointer_declaration_tac(childTac[1],childTac[2]); break; case INPUT: result = tac(TAC_READ, NULL, childTac[0]->destination, NULL); break; case OUTPUT: result = output_tac(childTac[0]); break; case FUNCTIONDEFINITION: result = fun_def_tac(ast->child[0]->child[1]->node, childTac[0], childTac[1], childTac[2]); break; case PARAMETERLIST: result = get_args_tac(childTac); break; case BLOCK: case COMMANDLIST: case PROGRAM: default: result = append(append(append(childTac[0], childTac[1]), childTac[2]), childTac[3]); break; } return result; }
BlockStmt* ForLoop::buildForLoop(Expr* indices, Expr* iteratorExpr, BlockStmt* body, bool coforall, bool zippered) { VarSymbol* index = newTemp("_indexOfInterest"); VarSymbol* iterator = newTemp("_iterator"); CallExpr* iterInit = 0; CallExpr* iterMove = 0; ForLoop* loop = new ForLoop(index, iterator, body, zippered); LabelSymbol* continueLabel = new LabelSymbol("_continueLabel"); LabelSymbol* breakLabel = new LabelSymbol("_breakLabel"); BlockStmt* retval = new BlockStmt(); iterator->addFlag(FLAG_EXPR_TEMP); // Unzippered loop, treat all objects (including tuples) the same if (zippered == false) { iterInit = new CallExpr(PRIM_MOVE, iterator, new CallExpr("_getIterator", iteratorExpr)); // try to optimize anonymous range iteration tryToReplaceWithDirectRangeIterator(iteratorExpr); } // Zippered loop: Expand args to a tuple with an iterator for each element. else { CallExpr* zipExpr = toCallExpr(iteratorExpr); if (zipExpr && zipExpr->isPrimitive(PRIM_ZIP)) { // The PRIM_ZIP indicates this is a new-style zip() AST. // Expand arguments to a tuple with appropriate iterators for each value. // // Specifically, change: // zip(a, b, c, ...) // into the tuple: // (_getIterator(a), _getIterator(b), _getIterator(c), ...) // // (ultimately, we will probably want to make this style of // rewrite into a utility function for the other get*Zip // functions as we convert parallel loops over to use PRIM_ZIP). // zipExpr->primitive = NULL; // remove the primitive // If there's just one argument... if (zipExpr->argList.length == 1) { Expr* zipArg = zipExpr->argList.only(); CallExpr* zipArgCall = toCallExpr(zipArg); // ...and it is a tuple expansion '(...t)' then remove the // tuple expansion primitive and simply pass the tuple itself // to _getIteratorZip(). This will not require any more // tuples than the user introduced themselves. // if (zipArgCall && zipArgCall->isPrimitive(PRIM_TUPLE_EXPAND)) { zipExpr->baseExpr = new UnresolvedSymExpr("_getIteratorZip"); Expr* tupleArg = zipArgCall->argList.only(); tupleArg->remove(); zipArgCall->replace(tupleArg); } else { // ...otherwise, make the expression into a _getIterator() // call zipExpr->baseExpr = new UnresolvedSymExpr("_getIterator"); // try to optimize anonymous range iteration tryToReplaceWithDirectRangeIterator(zipArg); } } else { // // Otherwise, if there's more than one argument, build up the // tuple by applying _getIterator() to each element. // zipExpr->baseExpr = new UnresolvedSymExpr("_build_tuple"); Expr* arg = zipExpr->argList.first(); while (arg) { Expr* next = arg->next; Expr* argCopy = arg->copy(); arg->replace(new CallExpr("_getIterator", argCopy)); // try to optimize anonymous range iteration tryToReplaceWithDirectRangeIterator(argCopy); arg = next; } } iterInit = new CallExpr(PRIM_MOVE, iterator, zipExpr); assert(zipExpr == iteratorExpr); } else { // // This is an old-style zippered loop so handle it in the old style // iterInit = new CallExpr(PRIM_MOVE, iterator, new CallExpr("_getIteratorZip", iteratorExpr)); // try to optimize anonymous range iteration if (CallExpr* call = toCallExpr(iteratorExpr)) if (call->isNamed("_build_tuple")) for_actuals(actual, call) tryToReplaceWithDirectRangeIterator(actual); } } index->addFlag(FLAG_INDEX_OF_INTEREST); iterMove = new CallExpr(PRIM_MOVE, index, new CallExpr("iteratorIndex", iterator)); if (indices == 0) indices = new UnresolvedSymExpr("chpl__elidedIdx"); checkIndices(indices); destructureIndices(loop, indices, new SymExpr(index), coforall); if (coforall) index->addFlag(FLAG_COFORALL_INDEX_VAR); loop->mContinueLabel = continueLabel; loop->mBreakLabel = breakLabel; loop->insertAtTail(new DefExpr(continueLabel)); retval->insertAtTail(new DefExpr(index)); retval->insertAtTail(new DefExpr(iterator)); retval->insertAtTail(iterInit); retval->insertAtTail(new BlockStmt(iterMove, BLOCK_TYPE)); retval->insertAtTail(loop); retval->insertAtTail(new DefExpr(breakLabel)); retval->insertAtTail(new CallExpr("_freeIterator", iterator)); return retval; }