Example #1
0
bool AMDGPUCodeGenPrepare::promoteUniformOpToI32(ICmpInst &I) const {
  assert(needsPromotionToI32(I.getOperand(0)->getType()) &&
         "I does not need promotion to i32");

  IRBuilder<> Builder(&I);
  Builder.SetCurrentDebugLocation(I.getDebugLoc());

  Type *I32Ty = getI32Ty(Builder, I.getOperand(0)->getType());
  Value *ExtOp0 = nullptr;
  Value *ExtOp1 = nullptr;
  Value *NewICmp  = nullptr;

  if (I.isSigned()) {
    ExtOp0 = Builder.CreateSExt(I.getOperand(0), I32Ty);
    ExtOp1 = Builder.CreateSExt(I.getOperand(1), I32Ty);
  } else {
    ExtOp0 = Builder.CreateZExt(I.getOperand(0), I32Ty);
    ExtOp1 = Builder.CreateZExt(I.getOperand(1), I32Ty);
  }
  NewICmp = Builder.CreateICmp(I.getPredicate(), ExtOp0, ExtOp1);

  I.replaceAllUsesWith(NewICmp);
  I.eraseFromParent();

  return true;
}
Example #2
0
/// restrictLoopBound - Op dominates loop body. Op compares an IV based value 
/// with a loop invariant value. Update loop's lower and upper bound based on 
/// the loop invariant value.
bool LoopIndexSplit::restrictLoopBound(ICmpInst &Op) {
  bool Sign = Op.isSigned();
  Instruction *PHTerm = L->getLoopPreheader()->getTerminator();

  if (IVisGT(*ExitCondition) || IVisGE(*ExitCondition)) {
    BranchInst *EBR = 
      cast<BranchInst>(ExitCondition->getParent()->getTerminator());
    ExitCondition->setPredicate(ExitCondition->getInversePredicate());
    BasicBlock *T = EBR->getSuccessor(0);
    EBR->setSuccessor(0, EBR->getSuccessor(1));
    EBR->setSuccessor(1, T);
  }

  LLVMContext &Context = Op.getContext();

  // New upper and lower bounds.
  Value *NLB = NULL;
  Value *NUB = NULL;
  if (Value *V = IVisLT(Op)) {
    // Restrict upper bound.
    if (IVisLE(*ExitCondition)) 
      V = getMinusOne(V, Sign, PHTerm, Context);
    NUB = getMin(V, IVExitValue, Sign, PHTerm);
  } else if (Value *V = IVisLE(Op)) {
    // Restrict upper bound.
    if (IVisLT(*ExitCondition)) 
      V = getPlusOne(V, Sign, PHTerm, Context);
    NUB = getMin(V, IVExitValue, Sign, PHTerm);
  } else if (Value *V = IVisGT(Op)) {
    // Restrict lower bound.
    V = getPlusOne(V, Sign, PHTerm, Context);
    NLB = getMax(V, IVStartValue, Sign, PHTerm);
  } else if (Value *V = IVisGE(Op))
    // Restrict lower bound.
    NLB = getMax(V, IVStartValue, Sign, PHTerm);

  if (!NLB && !NUB) 
    return false;

  if (NLB) {
    unsigned i = IndVar->getBasicBlockIndex(L->getLoopPreheader());
    IndVar->setIncomingValue(i, NLB);
  }

  if (NUB) {
    unsigned i = (ExitCondition->getOperand(0) != IVExitValue);
    ExitCondition->setOperand(i, NUB);
  }
  return true;
}
Example #3
0
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);
    }
  }
}
Example #4
0
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);
      }
    }
  }
}