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; }
/// 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; }
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); } } }
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); } } } }