void ConditionalConstantPropagation::ExampleCode(raw_ostream& O, Function& F) { std::set<StringRef> var_set; var_set.clear(); BasicBlock* bb_entry = NULL; BasicBlock* bb_if_then = NULL; BasicBlock* bb_if_else = NULL; BasicBlock* bb_if_end = NULL; // TA: The fol lowing code shows how you iterate over variables // defined in this function O << "All Variables Defined in Function " << F.getName() << "\n"; for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI) { BasicBlock* BB = dyn_cast<BasicBlock>(&*FI); for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE; ++BI) { Instruction *instr = dyn_cast<Instruction>(&*BI); LatticeMap[instr] = new Lattice(); LatticeMap[instr]->TOP = true; LatticeMap[instr]->BOT = false; if ( BI->hasName() ) { StringRef var_name = BI->getValueName()->first(); O << "VARIABLE:\t" << var_name << "\tdefined in "; BI->print(O); O << "\n"; } } if ( !bb_entry ) bb_entry = BB; else if ( !bb_if_then ) bb_if_then = BB; else if ( !bb_if_else ) bb_if_else = BB; else if ( !bb_if_end ) bb_if_end = BB; } /* //intialization CFGWorklist.push(bb_entry); //need to initialize bb_entry as the first node, caution: I do not know what entry node contains for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI) { BasicBlock* BB = dyn_cast<BasicBlock>(&*FI); ExecutableMap[BB->getName()] = 0; int count = 0; for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) { count++; } ExecutableMax[BB->getName()] = count; } //initialize the VALUE OBJECTS (THIS SHOULD ALREADY BE DONE ABOVE IN EXAMPLE CODE) while (CFGWorklist.size()!=0 || SSAWorklist.size()!=0) { while(CFGWorklist.size()!=0) { BasicBlock* BB = CFGWorklist.front(); CFGWorklist.pop(); if((ExecutableMap[BB->getName()]==0) || (ExecutableMap[BB->getName()] < ExecutableMax[BB->getName()] )) { ExecutableMap[BB->getName()]+=1; //evaluate each phi-function in BB <----- can this be done in Evaluate()? for (BasicBlock::iterator BI = BB->begin(), BE = BB->end();BI != BE; ++BI) { //evaluate BI (and update lattice?) <------ Instruction* definition = dyn_cast<Instruction> (&*BI); O<< "reached before evaluate" << *definition << BB->getName()<<"\n"; O << "\ninst lattice of:" << *definition << "\n \t\t--TOP ::" << LatticeMap[definition]->TOP <<" \t " << "BOT::"<< LatticeMap[definition]->BOT <<" \t " << "constant:: " << LatticeMap[definition]->constant <<" \n\n " ; *LatticeMap[definition] = Evaluate(O,definition); O<< "reached after evaluate" << *definition << BB->getName()<<"\n"; O << "\ninst lattice of:" << *definition << "\n \t\t--TOP ::" << LatticeMap[definition]->TOP <<" \t " << "BOT::"<< LatticeMap[definition]->BOT <<" \t " << "constant:: " << LatticeMap[definition]->constant <<" \n\n " ; for (Instruction::use_iterator UI= definition->use_begin(), UE=definition->use_end(); UI!=UE; ++UI) { Instruction* usage = dyn_cast<Instruction> (*UI); ///NOTE, WE CANNOT DO &* HERE LIKE FOR 'definition' ABOVE. DOES THIS CAUSE PROBLEMS?? BasicBlock* parent = usage->getParent(); if (ExecutableMap[parent->getName()] > 0) { SSAWorklist.push(usage); } //DEBUGGING CODE IS COMMENTED OUT BELOW: //if ( UI->hasName() ) //{ //StringRef var_name = BI->getValueName()->first(); //O << "USE :::" << UI->getValueName()->first()<<" " << "VARIABLE:\t" << var_name<<"\tdefined in "; //UI->print(O); //O << "\n"; //} } } } } while(SSAWorklist.size()!=0) { Instruction* instr = SSAWorklist.front(); SSAWorklist.pop(); O << "SSA before evaluate" << *instr << "\n"; O << "\ninst lattice of:" << *instr << "\n \t\t--TOP ::" << LatticeMap[instr]->TOP <<" \t " << "BOT::"<< LatticeMap[instr]->BOT <<" \t " << "constant:: " << LatticeMap[instr]->constant <<" \n\n " ; Lattice t = Evaluate(O,instr);// ********** need to make evaluate function O << "SSA after evaluate" << *instr << "\n"; O << "\ninst lattice of:" << *instr << "\n \t\t--TOP ::" << LatticeMap[instr]->TOP <<" \t " << "BOT::"<< LatticeMap[instr]->BOT <<" \t " << "constant:: " << LatticeMap[instr]->constant <<" \n\n " ; if (!LatEquals(t,*LatticeMap[instr])) //do get equals function { //O << "\ninst values change from:" << *instr << "\n \t\t--TOP ::" << LatticeMap[instr]->TOP <<" \t " << "BOT::"<< LatticeMap[instr]->BOT <<" \t " << "constant:: " << LatticeMap[instr]->constant <<" \n\n " ; *LatticeMap[instr] = MeetFunc(*LatticeMap[instr],t); //O << "\ninst values change2:" << *instr << "\n \t\t--TOP ::" << LatticeMap[instr]->TOP <<" \t " << "BOT::"<< LatticeMap[instr]->BOT <<" \t " << "constant:: " << LatticeMap[instr]->constant <<" \n\n " ; for (Instruction::use_iterator UI= instr->use_begin(), UE=instr->use_end(); UI!=UE; ++UI) { Instruction* usage = dyn_cast<Instruction> (*UI); BasicBlock* parent = usage->getParent(); if (ExecutableMap[parent->getName()] > 0) { SSAWorklist.push(usage); } } } } } for (std::map<Instruction*, Lattice*> ::iterator it = LatticeMap.begin(); it!= LatticeMap.end(); ++it) { O << "\ninst ::" << *(it->first) << "\n \t\t--TOP ::" << it->second->TOP <<" \t " << "BOT::"<<it->second->BOT <<" \t " << "constant:: " << it->second->constant <<" \n\n " ; } /* for (std::map<Instruction*, Lattice*> ::iterator it = LatticeMap.begin(); it!= LatticeMap.end(); ++it) { Instruction * instr = dyn_cast<Instruction> (&*(it->first)); O << *instr << "\n"; if ( !(LatticeMap[instr]->TOP || LatticeMap[instr]->BOT) ) { BasicBlock::iterator ii(instr); if( ICmpInst * icmpinst = dyn_cast<ICmpInst>(&*instr) ) { int64_t taken = LatticeMap[instr]->constant; Constant *x = ConstantInt::get(instr->getType(), 0x1); ConstantInt *ret1 = dyn_cast<ConstantInt>(&*x); x = ConstantInt::get(instr->getType(), 0x0); ConstantInt *ret0 =dyn_cast<ConstantInt>(&*x); if(taken == 0) { llvm::ReplaceInstWithValue(instr->getParent()->getInstList(),ii,ret0); } else { llvm::ReplaceInstWithValue(instr->getParent()->getInstList(),ii,ret1); } } else if( isa<PHINode>(instr) ) { int64_t lat_constant = LatticeMap[instr]->constant; // convert lat_constant to ConstantInt Constant * newConst = ConstantInt::getSigned(instr->getType(),lat_constant); if (ConstantInt * ptr = dyn_cast<ConstantInt>(newConst)) { ReplaceInstWithValue(instr->getParent()->getInstList(), ii, ptr); } } else if ( BranchInst *BI = dyn_cast<BranchInst>(instr)) { int64_t taken = LatticeMap[instr]->constant; if(taken == 0) { O << *instr << " replacing with false value\n"; //BranchInst * new_branch = BranchInst::Create(BI->getSuccessor(0),BI->getSuccessor(1),cast<Value>(&*ConstantInt::getFalse(BI->getContext()))); BranchInst * new_branch = BranchInst::Create(BI->getSuccessor(1)); O << *new_branch << " <- false value\n"; ReplaceInstWithInst(BI->getParent()->getInstList(), ii, cast<Instruction>(&*new_branch)); } else { O << *instr << " replacing with true value\n"; BranchInst * new_branch = BranchInst::Create(BI->getSuccessor(0)); O << *new_branch << " <- true value\n"; ReplaceInstWithInst(BI->getParent()->getInstList(), ii, cast<Instruction>(&*new_branch)); } } else if ( instr->getOpcode() == Instruction::Sub || instr->getOpcode() == Instruction::Add) { int64_t lat_constant = LatticeMap[instr]->constant; // convert lat_constant to ConstantInt Constant * newConst = ConstantInt::getSigned(instr->getType(),lat_constant); if (ConstantInt * ptr = dyn_cast<ConstantInt>(newConst)) { ReplaceInstWithValue(instr->getParent()->getInstList(), ii, ptr); } } } } /*my propagation code: for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI) { BasicBlock* BB = dyn_cast<BasicBlock>(&*FI); for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE; ++BI) { } }*/ /* after running the above code for(each value in "Value" map) { if( value is not TOP or BOT) { set original instruction RHS equal to value } } run simplify cfg to eliminate deadcode (values with TOP) */ /* //TA: The following code examines the last instruction of // each basic block, and print if the last instruction is // condtional or unconditional branch for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI) { BasicBlock* BB = dyn_cast<BasicBlock>(&*FI); O << "----------------------------------------------------\n"; O << "BB: " << BB ->getName() << '\n'; TerminatorInst *TI = BB->getTerminator(); O << "\tTerminatorInst: " << *TI << '\n'; if (BranchInst *BI = dyn_cast<BranchInst>(TI)) { if (BI->isUnconditional()) O << "\tInstruction is uncondtional\n"; else { O << "\tInstruction is conditional\n"; Value * condition = BI->getCondition(); O << "\t\tcondtion is " << *condition << "\n"; } } } // TA: the following code shows how to perform the symbolic execution for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI) { BasicBlock* BB = dyn_cast<BasicBlock>(&*FI); for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE; ++BI) { if ( BI->getOpcode() == Instruction::Sub) { O << "Sub Instr: " << *BI << "\n"; unsigned operand_size = BI->getNumOperands(); assert ( operand_size == 2 ); if ( dyn_cast<ConstantInt>(&*BI->getOperand(0)) && dyn_cast<ConstantInt>(&*BI->getOperand(1)) ) { Constant * expr_result = ConstantExpr::getSub(dyn_cast<Constant>(&*BI->getOperand(0)), dyn_cast<Constant>(&*BI->getOperand(1)) ); if ( ConstantInt * int_result = dyn_cast<ConstantInt>(&*expr_result) ) { O << "Both operands are constant, result is: " << int_result->getValue() << "\n"; // replace instruction using // ReplaceInstWithValue //BasicBlock::iterator ii(instToReplace); ReplaceInstWithValue(BI->getParent()->getInstList(), BI, int_result ); } } } } } // TA: the following code shows how to change the IF condition // when it always executes false path TerminatorInst *TI; TI = bb_entry->getTerminator(); O << "TerminatorInst in Entry Block: " << *TI; if (BranchInst *BI = dyn_cast<BranchInst>(TI)) { if (BI->isUnconditional()) O << " (Uncondtional)\n"; else if (BI->isConditional()) O << " (Condtional)\n"; } BasicBlock::iterator BI = bb_entry->begin(); if ( ICmpInst * icmpinst = dyn_cast<ICmpInst>(&*BI) ) { O << " ICmpInst " << *icmpinst << "\n"; if ( icmpinst->isSigned() ) { if (icmpinst->getSignedPredicate () == CmpInst::ICMP_SGT ) { O << icmpinst->getSignedPredicate () << ": int signed greater than\n"; Value * left_hand_side = icmpinst->getOperand(0); Value * right_hand_side = icmpinst->getOperand(1); if ( dyn_cast<ConstantInt> (&*left_hand_side) && dyn_cast<ConstantInt>(&*right_hand_side)) { ConstantInt * left_const = dyn_cast<ConstantInt> (&*left_hand_side); ConstantInt * right_const = dyn_cast<ConstantInt> (&*right_hand_side); O << "LHS is constant: " << *left_const << ", value: " << left_const->getValue() << "\n"; O << "RHS is constant: " << *right_const<< ", value: " << right_const->getValue() << "\n"; int64_t left_value = left_const->getValue().getSExtValue(); int64_t right_value = right_const->getValue().getSExtValue(); if ( left_value > right_value ) { O << "this if statement will always be true\n"; } else { O << "this if statement will always be false\n"; // if this is the case, we need to replace the terminator instruction (condtional branch ) with new one BasicBlock::iterator ii(TI); BranchInst * new_branch = BranchInst::Create(TI->getSuccessor(0),TI->getSuccessor(1),cast<Value>(&*ConstantInt::getFalse(TI->getContext()))); //TI->getParent()); ReplaceInstWithInst(TI->getParent()->getInstList(), ii, cast<Instruction>(&*new_branch)); } } } } }*/ }