/// MatchPointerHeuristic - Predict that a comparison of a pointer against /// null or of two pointers 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::MatchPointerHeuristic(BasicBlock *root) const { // Last instruction of basic block. TerminatorInst *TI = root->getTerminator(); // Basic block successors. 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(); // Pointer comparisons are integer comparisons. ICmpInst *II = dyn_cast<ICmpInst>(cond); if (!II) return empty; // An integer comparison has always two operands. Value *operand1 = II->getOperand(0); Value *operand2 = II->getOperand(1); // Obtain the type of comparison. enum ICmpInst::Predicate signedPred = II->getSignedPredicate(); // The heuristic states that it must be compared against null, // but in LLVM, null is also a PointerType, so it only requires // to test if there is a comparison between two pointers. if (signedPred == ICmpInst::ICMP_EQ && isa<PointerType>(operand1->getType()) && // NULL is a pointer type too isa<PointerType>(operand2->getType())) { // NULL is a pointer type too return std::make_pair(falseSuccessor, trueSuccessor); } else if (signedPred != ICmpInst::ICMP_EQ && isa<PointerType>(operand1->getType()) && isa<PointerType>(operand2->getType())) { return std::make_pair(trueSuccessor, falseSuccessor); } return empty; }
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); } } } }