void SymTable::generateGlobals(AsmCode &code) const { for(int i = 0; i < size(); i++){ VarSymbol *sym = dynamic_cast<VarSymbol*>(sym_ptr[i]); if(sym && !sym->type->isFunc()) sym->generate(code); } }
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; }
// ... of [const] in intent static VarSymbol* createCurrIN(ShadowVarSymbol* SI) { INT_ASSERT(!SI->isRef()); VarSymbol* currSI = new VarSymbol(SI->name, SI->type); currSI->qual = SI->isConstant() ? QUAL_CONST_VAL : QUAL_VAL; if (SI->isConstant()) currSI->addFlag(FLAG_CONST); return currSI; }
// ... for a task-private variable static VarSymbol* createCurrTPV(ShadowVarSymbol* TPV) { VarSymbol* currTPV = new VarSymbol(TPV->name, TPV->type); currTPV->qual = TPV->qual; if (TPV->hasFlag(FLAG_CONST)) currTPV->addFlag(FLAG_CONST); if (TPV->hasFlag(FLAG_REF_VAR)) currTPV->addFlag(FLAG_REF_VAR); return currTPV; }
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)); } } } } }
// // Consider a function that takes a formal of type Record by const ref // and that returns that value from the function. The compiler inserts // a PRIM_MOVE operation. // // This work-around inserts an autoCopy to compensate // void ReturnByRef::updateAssignmentsFromRefArgToValue(FnSymbol* fn) { std::vector<CallExpr*> callExprs; collectCallExprs(fn, callExprs); for (size_t i = 0; i < callExprs.size(); i++) { CallExpr* move = callExprs[i]; if (move->isPrimitive(PRIM_MOVE) == true) { SymExpr* lhs = toSymExpr(move->get(1)); SymExpr* rhs = toSymExpr(move->get(2)); if (lhs != NULL && rhs != NULL) { VarSymbol* symLhs = toVarSymbol(lhs->symbol()); ArgSymbol* symRhs = toArgSymbol(rhs->symbol()); if (symLhs != NULL && symRhs != NULL) { if (isUserDefinedRecord(symLhs->type) == true && symRhs->type == symLhs->type) { if (symLhs->hasFlag(FLAG_ARG_THIS) == false && (symRhs->intent == INTENT_REF || symRhs->intent == INTENT_CONST_REF)) { SET_LINENO(move); CallExpr* autoCopy = NULL; rhs->remove(); autoCopy = new CallExpr(autoCopyMap.get(symRhs->type), rhs); move->insertAtTail(autoCopy); } } } } } } }
void IpeModule::moduleAdd(IpeModule* module) { if (mEnv->findVariable(module->name()) != NULL) { printf("IpeModule::moduleAdd Unable to add module %s to module %s; already defined\n", module->name(), name()); } else { int offset = mEnv->allocateValue(module); VarSymbol* var = new VarSymbol(module->name(), gIpeTypeModule); var->addFlag(FLAG_CONST); var->locationSet(0, offset); mEnv->varAdd(var); } }
void IpeModuleRoot::init() { mState = kResolved; initialize(); for (int i = 1; i <= sHighWater; i++) { DefExpr* expr = toDefExpr(rootModule->block->body.get(i)); INT_ASSERT(expr); if (mEnv->findLocal(expr->sym->name) != NULL) { printf(" Attempt to redefine identifier %s\n", expr->sym->name); INT_ASSERT(false); } else if (TypeSymbol* sym = toTypeSymbol(expr->sym)) { int offset = mEnv->allocateValue(sym->type); VarSymbol* var = new VarSymbol(sym->name, gIpeTypeType); INT_ASSERT(expr->exprType == NULL); INT_ASSERT(expr->init == NULL); var->addFlag(FLAG_CONST); var->locationSet(0, offset); mEnv->varAdd(var); } else if (expr->sym->isImmediate() == true) { VarSymbol* var = toVarSymbol(expr->sym); int offset = mEnv->allocateValue(var->type); var->addFlag(FLAG_CONST); var->locationSet(0, offset); mEnv->varAdd(var); } else { AstDumpToNode logger(stdout, 3); printf("Unexpected expression while initializing RootModule\n"); printf(" "); expr->accept(&logger); printf("\n"); INT_ASSERT(false); } } moduleAdd(this); }
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; }
void IpeEnv::describe(const char* pad, int index, LcnSymbol* var) const { const char* symName = var->name; const char* typeName = ""; ArgSymbol* argSym = toArgSymbol(var); VarSymbol* varSym = toVarSymbol(var); if (var->type) typeName = var->type->symbol->name; printf("%s %5d: %-30s", pad, index, symName); if (argSym != NULL) { if (argSym->intent & INTENT_REF) printf("ref %-12s", typeName); else printf("arg %-12s", typeName); } else if (varSym->immediate != NULL) printf("const %-12s", typeName); else if (varSym->hasFlag(FLAG_CONST) == true) printf("const %-12s", typeName); else if (varSym->hasFlag(FLAG_PARAM) == true) printf("param %-12s", typeName); else printf("var %-12s", typeName); if (var->depth() >= 0 && var->offset() >= 0) printf("%4d %4d ", var->depth(), var->offset()); else printf(" "); if (argSym != NULL && (argSym->intent & INTENT_REF) != 0) { if (mFrameData != NULL) { int offset = argSym->offset(); IpeValue* ref = *((IpeValue**) (((char*) mFrameData) + offset)); printf("0x%012lX", (long) ref); } } else if (var->offset() < 0) ; else if (var->type == NULL) ; else if (var->type == gIpeTypeType) printf("%s", symName); else if (var->type == dtBool) { if (mDepth == 0 || mFrameData != NULL) printf("%s", (fetchBool(var) == true) ? "true" : "false"); } else if (var->type == dtInt[INT_SIZE_64]) { if (mDepth == 0 || mFrameData != NULL) printf("%8ld", fetchInteger(var)); } else if (var->type == dtReal[FLOAT_SIZE_64]) { if (mDepth == 0 || mFrameData != NULL) printf(" %8.2f", fetchReal(var)); } else if (var->type == gIpeTypeModule) { if (mDepth == 0 || mFrameData != NULL) { IpeModule* value = (IpeModule*) fetchPtr(var); printf("#<IpeModule %-20s 0x%012lX>", value->name(), (long) value); } } else if (var->type == gIpeTypeProcedure) { if (mDepth == 0 || mFrameData != NULL) { IpeProcedure* value = (IpeProcedure*) fetchPtr(var); if (value->methodCount() == 1) printf("#<IpeProcedure %-20s with %3d method 0x%012lX>", value->name(), value->methodCount(), (long) value); else printf("#<IpeProcedure %-20s with %3d methods 0x%012lX>", value->name(), value->methodCount(), (long) value); } } else printf("Really?? Really??"); printf("\n"); }
ExprNode* Parser :: ParseDeclaration(SymbolType* sym_type){ if (isEq(scan.Get(), _SEPARATION, ";")){ scan.Next(); return nullptr; } SymbolType* t_symbol; if (!sym_type) { t_symbol = ParseType(); }else t_symbol = sym_type; VarSymbol* var = nullptr; BinOpNode *node = nullptr; while(true){ Token *token; token = scan.Get(); if(isEq(token, _SEPARATION, ";" )&& (t_symbol->isStruct() || dynamic_cast<TypedefSymbol*>(t_symbol))) break; if (isEq(scan.Get(), _SEPARATION,"(")) var = ParseComplexDeclaration(t_symbol); else var = ParseIdentifier(t_symbol); if(symStack->tables.back()->find_symbol(var->name) == 0) symStack->add_symbol(var); if(isEq(scan.Get(), _OPERATION, "=")){ Token *asgn = scan.Get(); scan.Next(); ExprNode* Assing_operand = ParseExpr(priorityTable[","] + 1); node = new BinOpNode(asgn, new IdentifierNode(token, var), Assing_operand); if(dynamic_cast<ConstSymbolType*> (var->getType())) errorIf(!var->getType()->getType()->canConvertTo(node->right->getType()),"Cannot perform conversion",scan.Get() ); else node->getType(); blocks.top()->AddStatement(node); } if(isEq(scan.Get() ,_SEPARATION, ";") || isEq(scan.Get() ,_SEPARATION, "{")) break; errorIf(!isEq(scan.Get(), _OPERATION, ","), "Comma Expected"); scan.Next(); } if(isEq (scan.Get(),_SEPARATION,"{")){ FuncSymbol *func = dynamic_cast<FuncSymbol*>(var->type); errorIf(!func, "Unexpected brace", scan.Get()); errorIf((symStack->tables.size() != 1), "Can not define the function in the block", scan.Get()); parsingFunc = func; func->body = ParseBlock(); parsingFunc = 0; CheckReturn(func); if(func->name == "main") main_func = func; scan.Next(); } else scan.Next(); return node; }