void CallFrame::setCurrentVPC(Instruction* vpc) { CallSiteIndex callSite(vpc - codeBlock()->instructions().begin()); this[CallFrameSlot::argumentCount].tag() = static_cast<int32_t>(callSite.bits()); }
bool CallCandidate::unify(CallExpr * callExpr, BindingEnv & env, FormatStream * errStrm) { size_t argCount = callExpr_->argCount(); for (size_t argIndex = 0; argIndex < argCount; ++argIndex) { QualifiedType paramType = this->paramType(argIndex); AnalyzerBase::analyzeType(paramType, Task_PrepConversion); } if (!isTemplate_) { return true; } // Now, for each parameter attempt unification. SourceContext callSite(callExpr, NULL, callExpr); SourceContext candidateSite(method_, &callSite, method_, Format_Type); // Unify explicit template arguments with template parameters. if (spCandidate_ != NULL) { if (!spCandidate_->unify(&candidateSite, env)) { return false; } } //bool hasUnsizedArgs = false; for (size_t argIndex = 0; argIndex < argCount; ++argIndex) { Expr * argExpr = callExpr_->arg(argIndex); QualifiedType argType = argExpr->type(); QualifiedType paramType = this->paramType(argIndex); // Skip unsized type integers for now, we'll bind them on the second pass. if (!env.unify(&candidateSite, paramType, argType, Constraint::LOWER_BOUND)) { if (errStrm) { *errStrm << "Argument #" << argIndex + 1 << " type " << paramType << " failed to unify with " << argType; } return false; } } // Unify the return type QualifiedType expectedReturnType = callExpr_->expectedReturnType(); if (!expectedReturnType.isNull()) { if (!env.unify(&candidateSite, resultType_, expectedReturnType, Constraint::UPPER_BOUND)) { if (errStrm) { *errStrm << "Return type " << expectedReturnType << " failed to unify with " << resultType_; } return false; } } // A proper unification requires that each template parameter be bound to something. for (Defn * def = method_; def != NULL && !def->isSingular(); def = def->parentDefn()) { Template * ts = def->templateSignature(); if (ts != NULL) { size_t numParams = ts->typeParams()->size(); // For each template parameter, create a TypeAssignment instance. for (size_t i = 0; i < numParams; ++i) { const TypeVariable * var = ts->patternVar(i); const TypeAssignment * ta = env.getAssignment(var, this); if (ta->constraints().empty()) { if (errStrm) { *errStrm << "No binding for template parameter " << var << " in " << env; } return false; } } } } return true; }
void CallFrame::setCurrentVPC(Instruction* vpc) { CallSiteIndex callSite(vpc); this[CallFrameSlot::argumentCount].tag() = callSite.bits(); }
// Propagate conditions bool ConditionPropagator::runOnFunction(llvm::Function &F) { m_map.clear(); llvm::SmallVector<std::pair<const llvm::BasicBlock*, const llvm::BasicBlock*>, 32> backedgesVector; llvm::FindFunctionBackedges(F, backedgesVector); std::set<std::pair<const llvm::BasicBlock*, const llvm::BasicBlock*> > backedges; backedges.insert(backedgesVector.begin(), backedgesVector.end()); if (m_debug) { std::cout << "========================================" << std::endl; } for (llvm::Function::iterator bbi = F.begin(), bbe = F.end(); bbi != bbe; ++bbi) { llvm::BasicBlock *bb = &*bbi; std::set<llvm::BasicBlock*> preds; for (llvm::Function::iterator tmpi = F.begin(), tmpe = F.end(); tmpi != tmpe; ++tmpi) { if (isPred(&*tmpi, bb) && backedges.find(std::make_pair(&*tmpi, bb)) == backedges.end()) { if (m_debug) { std::cout << bb->getName().str() << " has non-backedge predecessor " << tmpi->getName().str() << std::endl; } preds.insert(&*tmpi); } } std::set<llvm::Value*> trueSet; std::set<llvm::Value*> falseSet; bool haveStarted = false; for (std::set<llvm::BasicBlock*>::iterator i = preds.begin(), e = preds.end(); i != e; ++i) { TrueFalseMap::iterator it = m_map.find(*i); if (it == m_map.end()) { std::cerr << "Did not find condition information for predecessor " << (*i)->getName().str() << "!" << std::endl; exit(99999); } if (!haveStarted) { trueSet = it->second.first; falseSet = it->second.second; haveStarted = true; } else { // intersect trueSet = intersect(trueSet, it->second.first); falseSet = intersect(falseSet, it->second.second); } } if (preds.size() == 1) { llvm::BasicBlock *pred = *(preds.begin()); // branch condition! if (!m_onlyLoopConditions || m_lcbs.find(pred) != m_lcbs.end()) { llvm::TerminatorInst *termi = pred->getTerminator(); if (llvm::isa<llvm::BranchInst>(termi)) { llvm::BranchInst *br = llvm::cast<llvm::BranchInst>(termi); if (br->isConditional()) { if (br->getSuccessor(0) == bb) { // branch on true trueSet.insert(br->getCondition()); } else { // branch on false falseSet.insert(br->getCondition()); } } } } // assumes! if (!m_onlyLoopConditions) { for (llvm::BasicBlock::iterator insti = pred->begin(), inste = pred->end(); insti != inste; ++insti) { if (llvm::isa<llvm::CallInst>(insti)) { llvm::CallInst *ci = llvm::cast<llvm::CallInst>(insti); llvm::Function *calledFunction = ci->getCalledFunction(); if (calledFunction != NULL) { std::string functionName = calledFunction->getName().str(); if (functionName == "__kittel_assume") { llvm::CallSite callSite(ci); trueSet.insert(callSite.getArgument(0)); } } } } } } if (m_debug) { std::cout << "In " << bb->getName().str() << ":" << std::endl; std::cout << "TRUE: "; printSet(trueSet); std::cout << std::endl; std::cout << "FALSE: "; printSet(falseSet); std::cout << std::endl; if (++bbi != bbe) { std::cout << std::endl; } --bbi; } m_map.insert(std::make_pair(bb, std::make_pair(trueSet, falseSet))); } return false; }