コード例 #1
0
ファイル: RAFlowFunction.cpp プロジェクト: cLuuLess/cse231
void RAFlowFunction::visitBranchInst(BranchInst &BI){
  RALatticePoint* inRLP = new RALatticePoint(*(info_in_casted.back()));
  info_in_casted.pop_back();
  
  if (BI.isUnconditional()) {
    for (std::map<Value *, LatticePoint *>::iterator it=out_map.begin(); it != out_map.end(); ++it){
      Value* elm = it->first;
      out_map[elm] = new RALatticePoint(*inRLP);
    }
  }
  else{
    Value* cond = BI.getCondition();
    if (isa<ICmpInst>(cond)) {
      // may affect elements of our lattice.
      std::pair<Use*, Use *> branches = helper::getBranches(BI);
      Use* true_branch = branches.first;
      Use* false_branch = branches.second;
      /*
      errs() << "Examining instruction" << BI << "\n";
      errs() << "True branch is " << * (true_branch->get()) << "\n";
      errs() << "False branch is " << * (false_branch->get()) << "\n";
      */
      
      ICmpInst* cmp = cast<ICmpInst>(cond);
      std::pair<Use*, Use *> operands = helper::getOperands(*cmp);
      Use* right_hand_side = operands.second;
      Use*  left_hand_side = operands.first;
      
      /*
      errs() << "Comparison " << *cmp << "\n";
      errs() << "Left hand side is " << * (left_hand_side->get()) << "\n";
      errs() << "Right hand side is " << * (right_hand_side->get()) << "\n";
      */
      ConstantRange* lhs_range;
      ConstantRange* rhs_range;
      
      
      if (inRLP->representation.count(left_hand_side->get()) > 0) {
        lhs_range = inRLP->representation[left_hand_side->get()];
      }
      else if (isa<ConstantInt>(left_hand_side->get())) {
        ConstantInt* C2 = cast<ConstantInt>(left_hand_side->get());
        lhs_range = new ConstantRange(C2->getValue());
      }
      else{
        lhs_range = new ConstantRange(32, false);
      }
      
      if (inRLP->representation.count(right_hand_side->get()) > 0) {
        rhs_range = inRLP->representation[right_hand_side->get()];
      }
      else if (isa<ConstantInt>(right_hand_side->get())) {
        ConstantInt* C2 = cast<ConstantInt>(right_hand_side->get());
        rhs_range = new ConstantRange(C2->getValue());
      }
      else{
        rhs_range = new ConstantRange(32, false);
      }
      /*
      errs() << "Left hand side has range ";
      lhs_range->print(errs());
      errs() << "\nRight hand side has range ";
      rhs_range->print(errs());
      errs() << " \n ";
      */
      // First we compute the restrictions that cmp makes upon the regions.
      
      //errs() << " Compare looks like " << *cmp << "\n";

      int predicate = 0;
      
      if (cmp->isSigned()) {
        predicate = cmp->getSignedPredicate();
      }
      else{
        predicate = cmp->getUnsignedPredicate();
      }
      
      ConstantRange true_branch_lhs_restriction = ConstantRange::makeICmpRegion(predicate, *rhs_range);
      
      /*
      errs() << "True branch lhs_restriction: ";
      true_branch_lhs_restriction.print(errs());
      errs() << "\n";
      */
      
      ConstantRange false_branch_lhs_restriction = (ConstantRange(32, true)).difference(true_branch_lhs_restriction);
      
      /*
      errs() << "False branch lhs_restriction: ";
      false_branch_lhs_restriction.print(errs());
      errs() << "\n";
      */
      
      cmp->swapOperands();
      
      //errs() << " After swapping, compare looks like " << *cmp << "\n";

      
      ConstantRange true_branch_rhs_restriction = ConstantRange::makeICmpRegion(predicate,*lhs_range);
      
      /*
      errs() << "\nTrue branch rhs_restriction: ";
      true_branch_rhs_restriction.print(errs());
      errs() << " is it wrapped range? " << true_branch_rhs_restriction.isSignWrappedSet() << " is it empty? " << true_branch_rhs_restriction.isEmptySet() << " what is its size? " << true_branch_rhs_restriction.getSetSize() << "\n";
      */
      
      ConstantRange false_branch_rhs_restriction = (ConstantRange(32, true)).difference(true_branch_rhs_restriction);
      
      /*
      errs() << "False branch rhs_restriction: ";
      false_branch_rhs_restriction.print(errs());
      errs() << "\n";
      
      
      */
      
      cmp->swapOperands();
      
      // Next we intersect the ranges with the resulting restrictions.
      ConstantRange* true_branch_lhs_range = new ConstantRange(lhs_range->getBitWidth(), true);
      ConstantRange* false_branch_lhs_range = new ConstantRange(lhs_range->getBitWidth(), true);
      ConstantRange* true_branch_rhs_range = new ConstantRange(rhs_range->getBitWidth(), true);
      ConstantRange* false_branch_rhs_range = new ConstantRange(rhs_range->getBitWidth(), true);
      
      *true_branch_lhs_range = lhs_range->intersectWith(true_branch_lhs_restriction);
      *false_branch_lhs_range = lhs_range->intersectWith(false_branch_lhs_restriction);
      
      *true_branch_rhs_range = rhs_range->intersectWith(true_branch_rhs_restriction);
      *false_branch_rhs_range = rhs_range->intersectWith(false_branch_rhs_restriction);
      
      /*
      errs() << "True branch lhs range ";
      true_branch_lhs_range->print(errs());
      errs() << "\n";
      
      
      errs() << "False branch lhs range ";
      false_branch_lhs_range->print(errs());
      errs() << "\n";
      
      
      errs() << "True branch rhs range ";
      true_branch_rhs_range->print(errs());
      errs() << "\n";
      
      
      errs() << "False branch rhs range ";
      false_branch_rhs_range->print(errs());
      errs() << "\n";
      */
      
      RALatticePoint* true_branchRLP = new RALatticePoint(*inRLP);
      RALatticePoint* false_branchRLP = new RALatticePoint(*inRLP);
      
      
      true_branchRLP->isBottom = false;
      true_branchRLP->isTop = false;

      false_branchRLP->isBottom = false;
      false_branchRLP->isTop = false;

      if (inRLP->representation.count(left_hand_side->get()) > 0){
        //errs() << "\nIn if statement for lhs \n";

        
        true_branchRLP->representation[left_hand_side->get()] = true_branch_lhs_range;
        false_branchRLP->representation[left_hand_side->get()] = false_branch_lhs_range;
        /*
        errs() << "True branch lhs range ";
        true_branch_lhs_range->print(errs());
        errs() << "\n";
        
        
        errs() << "False branch lhs range ";
        false_branch_lhs_range->print(errs());
        errs() << "\n";
         */
      }
      if (inRLP->representation.count(right_hand_side->get()) > 0){
        //errs() << "\nIn if statement for rhs \n";
        
        true_branchRLP->representation[right_hand_side->get()] = true_branch_rhs_range;
        false_branchRLP->representation[right_hand_side->get()] = false_branch_rhs_range;
        /*
        errs() << "True branch rhs range ";
        true_branch_rhs_range->print(errs());
        errs() << "\n";
        
        
        errs() << "False branch rhs range ";
        false_branch_rhs_range->print(errs());
        errs() << "\n";
        */
      }
      /*
       info_out.push_back(true_branchRLP);
       info_out.push_back(false_branchRLP);
      */
      
      out_map[true_branch->get()] = true_branchRLP;
      /*
      errs() << "\nTrue branch lattice point is ";
      true_branchRLP->printToErrs();
      */
      out_map[false_branch->get()] = false_branchRLP;
      /*
      errs() << "\nFalse branch lattice point is ";
      false_branchRLP->printToErrs();
      */
    }
    else{
      // does not affect our lattice.
      for (std::map<Value *, LatticePoint *>::iterator it=out_map.begin(); it != out_map.end(); ++it){
        Value* elm = it->first;
        out_map[elm] = new RALatticePoint(*inRLP);
      }
    }
  }
}
コード例 #2
0
ファイル: CPFlowFunction.cpp プロジェクト: cLuuLess/cse231
void CPFlowFunction::visitBranchInst(BranchInst &BI) {
  CPLatticePoint* result = new CPLatticePoint(*(info_in_casted.back()));
  info_in_casted.pop_back();
  BranchInst* current = &BI;

  if (BI.isConditional()) {
    Value* cond = BI.getCondition();
    if (isa<ICmpInst>(cond)) {
      std::pair<Use*, Use *> branches = helper::getOps(BI);
      Use* true_branch = branches.first;
      Use* false_branch = branches.second;

      ICmpInst* cmp = dyn_cast<ICmpInst>(cond);
      std::pair<Use*, Use *> operands = helper::getOps(*cmp);
      Use* rhs = operands.second;
      Use* lhs = operands.first;

      ConstantInt* rhs_const = NULL;
      ConstantInt* lhs_const = NULL;
      // get the rhs/lhs as a constant int
      if (isa<ConstantInt>(rhs)) {
        rhs_const = dyn_cast<ConstantInt>(rhs);
      } else if (result->representation.count(rhs->get()) > 0) {
        rhs_const = result->representation[rhs->get()];
      } else {
        rhs_const = ConstantInt::get(context, llvm::APInt(32, 0, true));
      } 
      if (isa<ConstantInt>(lhs)) {
        lhs_const = dyn_cast<ConstantInt>(lhs->get());
      } else if (result->representation.count(lhs->get()) > 0) {
        lhs_const = result->representation[lhs->get()];
      } else {
        lhs_const = ConstantInt::get(context, llvm::APInt(32, 0, true));
      }

      // Create successors
      CPLatticePoint* true_branchCLP = new CPLatticePoint(false, false, std::map<Value*,ConstantInt*>(result->representation));
      CPLatticePoint* false_branchCLP = new CPLatticePoint(false, false, std::map<Value*,ConstantInt*>(result->representation));

      // get the predicate
      int predicate = 0;
      predicate = cmp->isSigned() ? cmp->getSignedPredicate() : cmp->getUnsignedPredicate();
      if (predicate == CmpInst::ICMP_EQ) {
        if (isa<ConstantInt>(lhs)) {
           true_branchCLP->representation[rhs->get()] = lhs_const;
        } else if (isa<ConstantInt>(rhs)) {
           true_branchCLP->representation[lhs->get()] = rhs_const;
        }
        out_map[true_branch->get()] = true_branchCLP;
        out_map[false_branch->get()] = false_branchCLP;
      } else if (predicate == CmpInst::ICMP_NE) {
        if (isa<ConstantInt>(lhs)) {
           false_branchCLP->representation[rhs->get()] = lhs_const;
        } else if (isa<ConstantInt>(rhs)) {
           false_branchCLP->representation[lhs->get()] = rhs_const;
        }
        out_map[true_branch->get()] = true_branchCLP;
        out_map[false_branch->get()] = false_branchCLP;
      } else {
        for (std::map<Value *, LatticePoint *>::iterator it=out_map.begin(); it != out_map.end(); ++it){
          Value* elm = it->first;
          out_map[elm] = new CPLatticePoint(*result);
        }
      }
    } else {
      for (std::map<Value *, LatticePoint *>::iterator it=out_map.begin(); it != out_map.end(); ++it){
        Value* elm = it->first;
        out_map[elm] = new CPLatticePoint(*result);
      }
    }
  } else {
    for (std::map<Value *, LatticePoint *>::iterator it=out_map.begin(); it != out_map.end(); ++it){
        Value* elm = it->first;
        out_map[elm] = new CPLatticePoint(*result);
    }
  }
}
コード例 #3
0
/// MatchOpcodeHeuristic - Predict that a comparison of an integer for less
/// than zero, less than or equal to zero, or equal to a constant, will
/// fail.
/// @returns a Prediction that is a pair in which the first element is the
/// successor taken, and the second the successor not taken.
Prediction BranchHeuristicsInfo::MatchOpcodeHeuristic(BasicBlock *root) const {
  // Last instruction of basic block.
  TerminatorInst *TI = root->getTerminator();

  // Basic block successors, the true and false branches.
  BasicBlock *trueSuccessor = TI->getSuccessor(0);
  BasicBlock *falseSuccessor = TI->getSuccessor(1);

  // Is the last instruction a Branch Instruction?
  BranchInst *BI = dyn_cast<BranchInst>(TI);
  if (!BI || !BI->isConditional())
    return empty;

  // Conditional instruction.
  Value *cond = BI->getCondition();

  // Heuristics can only apply to integer comparisons.
  ICmpInst *II = dyn_cast<ICmpInst>(cond);
  if (!II)
    return empty;

  // An integer comparison has always to operands.
  Value *operand1 = II->getOperand(0);
  ConstantInt *op1const = dyn_cast<ConstantInt>(operand1);

  Value *operand2 = II->getOperand(1);
  ConstantInt *op2const = dyn_cast<ConstantInt>(operand2);

  // The type of comparison used.
  enum ICmpInst::Predicate pred = II->getUnsignedPredicate();

  // The return successors (the first taken and the second not taken).
  Edge falseEdge = std::make_pair(falseSuccessor, trueSuccessor);
  Edge trueEdge  = std::make_pair(trueSuccessor, falseSuccessor);

  // Check several comparison operators.
  switch (pred) {
    case ICmpInst::ICMP_EQ: // if ($var == constant) or if (constant == $var).
      // If it's a equal comparison against a constant integer, match.
      if (op1const || op2const)
        return falseEdge;

      break;
    case ICmpInst::ICMP_NE: // if ($var != constant) or if (constant != $var).
      // If it's a not equal comparison against a constant integer, match.
      if (op1const || op2const)
        return trueEdge;

      break;
    case ICmpInst::ICMP_SLT: // if ($var < 0) or if (0 < $var).
    case ICmpInst::ICMP_ULT:
      if (!op1const && (op2const && op2const->isZero()))
        return falseEdge;
      else if (!op2const && (op1const && op1const->isZero()))
        return trueEdge;

      break;
    case ICmpInst::ICMP_SLE: // if ($var <= 0) or if (0 <= $var).
    case ICmpInst::ICMP_ULE:
      if (!op1const && (op2const && op2const->isZero()))
        return falseEdge;
      else if (!op2const && (op1const && op1const->isZero()))
        return trueEdge;

      break;
    case ICmpInst::ICMP_SGT: // if ($var > 0) or if (0 > $var).
    case ICmpInst::ICMP_UGT:
      if (!op1const && (op2const && op2const->isZero()))
        return trueEdge;
      else if (!op2const && (op1const && op1const->isZero()))
        return falseEdge;

      break;
    case ICmpInst::ICMP_SGE: // if ($var >= 0) or if (0 >= $var).
    case ICmpInst::ICMP_UGE:
      if (!op1const && (op2const && op2const->isZero()))
        return trueEdge;
      else if (!op2const && (op1const && op1const->isZero()))
        return falseEdge;

      break;
    default: // Do not process any other comparison operators.
      break;
  }

  // Heuristic not matched.
  return empty;
}