void deadVariableElimination(FnSymbol* fn) { Vec<Symbol*> symSet; Vec<SymExpr*> symExprs; collectSymbolSetSymExprVec(fn, symSet, symExprs); Map<Symbol*,Vec<SymExpr*>*> defMap; Map<Symbol*,Vec<SymExpr*>*> useMap; buildDefUseMaps(symSet, symExprs, defMap, useMap); forv_Vec(Symbol, sym, symSet) { // We're interested only in VarSymbols. if (!isVarSymbol(sym)) continue; // A method must have a _this symbol, even if it is not used. if (sym == fn->_this) continue; if (isDeadVariable(sym, defMap, useMap)) { for_defs(se, defMap, sym) { CallExpr* call = toCallExpr(se->parentExpr); INT_ASSERT(call && (call->isPrimitive(PRIM_MOVE) || call->isPrimitive(PRIM_ASSIGN))); Expr* rhs = call->get(2)->remove(); if (!isSymExpr(rhs)) call->replace(rhs); else call->remove(); } sym->defPoint->remove(); } }
static void removeVoidReturn(BlockStmt* cloneBody) { CallExpr* retexpr = toCallExpr(cloneBody->body.tail); INT_ASSERT(retexpr && retexpr->isPrimitive(PRIM_RETURN)); INT_ASSERT(toSymExpr(retexpr->get(1))->symbol() == gVoid); retexpr->remove(); }
// // Determine the index type for a ParamForLoop. // // This implementation creates a range with low/high values and then // asks for its type. // Type* ParamForLoop::indexType() { SymExpr* lse = lowExprGet(); SymExpr* hse = highExprGet(); CallExpr* range = new CallExpr("chpl_build_bounded_range", lse->copy(), hse->copy()); Type* idxType = 0; insertBefore(range); resolveCall(range); if (FnSymbol* sym = range->isResolved()) { resolveFormals(sym); DefExpr* formal = toDefExpr(sym->formals.get(1)); if (toArgSymbol(formal->sym)->typeExpr) idxType = toArgSymbol(formal->sym)->typeExpr->body.tail->typeInfo(); else idxType = formal->sym->type; range->remove(); } else { INT_FATAL("unresolved range"); } return idxType; }
// Remove the return statement and the def of 'ret'. Return 'ret'. // See also removeRetSymbolAndUses(). static Symbol* removeParIterReturn(BlockStmt* cloneBody, Symbol* retsym) { CallExpr* retexpr = toCallExpr(cloneBody->body.tail); INT_ASSERT(retexpr && retexpr->isPrimitive(PRIM_RETURN)); if (retsym == NULL) { retsym = toSymExpr(retexpr->get(1))->symbol(); INT_ASSERT(retsym->type->symbol->hasFlag(FLAG_ITERATOR_RECORD)); } else { CallExpr* move = toCallExpr(retsym->getSingleDef()->getStmtExpr()); INT_ASSERT(move->isPrimitive(PRIM_MOVE) || move->isPrimitive(PRIM_ASSIGN)); retsym = toSymExpr(move->get(2))->symbol(); move->remove(); } retexpr->remove(); return retsym; }
void ResolutionCandidate::resolveTypeConstructor(CallInfo& info) { SET_LINENO(fn); // Ignore tuple constructors; they were generated // with their type constructors. if (fn->hasFlag(FLAG_PARTIAL_TUPLE) == false) { CallExpr* typeConstructorCall = new CallExpr(astr("_type", fn->name)); for_formals(formal, fn) { if (formal->hasFlag(FLAG_IS_MEME) == false) { if (fn->_this->type->symbol->hasFlag(FLAG_TUPLE)) { if (formal->instantiatedFrom != NULL) { typeConstructorCall->insertAtTail(formal->type->symbol); } else if (formal->hasFlag(FLAG_INSTANTIATED_PARAM)) { typeConstructorCall->insertAtTail(paramMap.get(formal)); } } else { if (strcmp(formal->name, "outer") == 0 || formal->type == dtMethodToken) { typeConstructorCall->insertAtTail(formal); } else if (formal->instantiatedFrom != NULL) { SymExpr* se = new SymExpr(formal->type->symbol); NamedExpr* ne = new NamedExpr(formal->name, se); typeConstructorCall->insertAtTail(ne); } else if (formal->hasFlag(FLAG_INSTANTIATED_PARAM)) { SymExpr* se = new SymExpr(paramMap.get(formal)); NamedExpr* ne = new NamedExpr(formal->name, se); typeConstructorCall->insertAtTail(ne); } } } } info.call->insertBefore(typeConstructorCall); // If instead we call resolveCallAndCallee(typeConstructorCall) // then the line number reported in an error would change // e.g.: domains/deitz/test_generic_class_of_sparse_domain // or: classes/diten/multipledestructor resolveCall(typeConstructorCall); INT_ASSERT(typeConstructorCall->isResolved()); resolveFunction(typeConstructorCall->resolvedFunction()); fn->_this->type = typeConstructorCall->resolvedFunction()->retType; typeConstructorCall->remove(); }
static bool removeIdentityDefs(Symbol* sym) { bool change = false; for_defs(def, defMap, sym) { CallExpr* move = toCallExpr(def->parentExpr); if (move && isMoveOrAssign(move)) { SymExpr* rhs = toSymExpr(move->get(2)); if (rhs && def->symbol() == rhs->symbol()) { move->remove(); change = true; } } }
static bool removeIdentityDefs(Symbol* sym) { bool change = false; for_defs(def, defMap, sym) { CallExpr* move = toCallExpr(def->parentExpr); if (move && move->isPrimitive(PRIM_MOVE)) { SymExpr* rhs = toSymExpr(move->get(2)); if (rhs && def->var == rhs->var) { move->remove(); change = true; } } }
CallExpr* ParamForLoop::foldForResolve() { SymExpr* idxExpr = indexExprGet(); SymExpr* lse = lowExprGet(); SymExpr* hse = highExprGet(); SymExpr* sse = strideExprGet(); if (!lse || !hse || !sse) USR_FATAL(this, "param for loop must be defined over a bounded param range"); VarSymbol* lvar = toVarSymbol(lse->var); VarSymbol* hvar = toVarSymbol(hse->var); VarSymbol* svar = toVarSymbol(sse->var); CallExpr* noop = new CallExpr(PRIM_NOOP); if (!lvar || !hvar || !svar) USR_FATAL(this, "param for loop must be defined over a bounded param range"); if (!lvar->immediate || !hvar->immediate || !svar->immediate) USR_FATAL(this, "param for loop must be defined over a bounded param range"); Symbol* idxSym = idxExpr->var; Symbol* continueSym = continueLabelGet(); Type* idxType = indexType(); IF1_int_type idxSize = (get_width(idxType) == 32) ? INT_SIZE_32 : INT_SIZE_64; // Insert an "insertion marker" for loop unrolling insertAfter(noop); if (is_int_type(idxType)) { int64_t low = lvar->immediate->to_int(); int64_t high = hvar->immediate->to_int(); int64_t stride = svar->immediate->to_int(); if (stride <= 0) { for (int64_t i = high; i >= low; i += stride) { SymbolMap map; map.put(idxSym, new_IntSymbol(i, idxSize)); copyBodyHelper(noop, i, &map, this, continueSym); } } else { for (int64_t i = low; i <= high; i += stride) { SymbolMap map; map.put(idxSym, new_IntSymbol(i, idxSize)); copyBodyHelper(noop, i, &map, this, continueSym); } } } else { INT_ASSERT(is_uint_type(idxType) || is_bool_type(idxType)); uint64_t low = lvar->immediate->to_uint(); uint64_t high = hvar->immediate->to_uint(); int64_t stride = svar->immediate->to_int(); if (stride <= 0) { for (uint64_t i = high; i >= low; i += stride) { SymbolMap map; map.put(idxSym, new_UIntSymbol(i, idxSize)); copyBodyHelper(noop, i, &map, this, continueSym); } } else { for (uint64_t i = low; i <= high; i += stride) { SymbolMap map; map.put(idxSym, new_UIntSymbol(i, idxSize)); copyBodyHelper(noop, i, &map, this, continueSym); } } } // Remove the "insertion marker" noop->remove(); // Replace the paramLoop with the NO-OP replace(noop); return noop; }