Example #1
0
void CallFrame::setCurrentVPC(Instruction* vpc)
{
    CallSiteIndex callSite(vpc - codeBlock()->instructions().begin());
    this[CallFrameSlot::argumentCount].tag() = static_cast<int32_t>(callSite.bits());
}
Example #2
0
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;
}
Example #3
0
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;
}