[llvm-commits] CVS: llvm/lib/Reoptimizer/Trigger/TriggerAuxillary.cpp
Anand Shukla
ashukla at cs.uiuc.edu
Sat May 31 21:36:24 PDT 2003
Changes in directory llvm/lib/Reoptimizer/Trigger:
TriggerAuxillary.cpp updated: 1.3 -> 1.4
---
Log message:
Trigger function modified to use the new bininterface for binary modification
---
Diffs of the changes:
Index: llvm/lib/Reoptimizer/Trigger/TriggerAuxillary.cpp
diff -u llvm/lib/Reoptimizer/Trigger/TriggerAuxillary.cpp:1.3 llvm/lib/Reoptimizer/Trigger/TriggerAuxillary.cpp:1.4
--- llvm/lib/Reoptimizer/Trigger/TriggerAuxillary.cpp:1.3 Wed Apr 23 11:37:37 2003
+++ llvm/lib/Reoptimizer/Trigger/TriggerAuxillary.cpp Sat May 31 21:35:06 2003
@@ -7,17 +7,39 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/Reoptimizer/BinInterface/sparcbin.h"
+#include "llvm/Reoptimizer/BinInterface/bitmath.h"
+#include "llvm/Reoptimizer/BinInterface/sparc9.h"
+#include "llvm/Reoptimizer/Mapping/LLVMinfo.h"
+#include "llvm/Reoptimizer/GetTraceTime.h"
+#include "llvm/Reoptimizer/TraceCache.h"
+#include "llvm/Reoptimizer/VirtualMem.h"
+#include "llvm/Reoptimizer/InstrUtils.h"
+#include "llvm/Bytecode/Reader.h"
+#include "llvm/Module.h"
#include "llvm/iTerminators.h"
-#include "llvm/Function.h"
#include "llvm/iOther.h"
+#include "llvm/iPHINode.h"
+#include "llvm/iMemory.h"
+#include "llvm/Support/CFG.h"
+#include "TriggerAuxillary.h"
#include <iostream>
+#include <fstream>
+#include <string>
+#include <algorithm>
#include <stdlib.h>
#include <vector>
#include <list>
#include <map>
+
using std::vector;
using std::map;
using std::list;
+using std::pair;
+
+extern int llvm_length;
+extern const unsigned char LLVMBytecode[];
+extern void** llvmFunctionTable[];
extern "C" void llvmInitializeCounter(int *cnt, int k){
for(int i=0; i<k; i++)
@@ -154,3 +176,436 @@
}
}
*/
+
+pair<unsigned char, unsigned char>
+getPHIRegister(PHINode *phi, VirtualMem *vm, TraceCache *tr,
+ map<PHINode *, char> &seenPHI){
+
+ //look for uses of phi
+ seenPHI[phi] = 1;
+
+ for(Value::use_iterator UI = phi->use_begin(), UE = phi->use_end();
+ UI != UE; ++UI){
+ Instruction *in = dyn_cast<Instruction>(*UI);
+ assert(in); //phi must be used in an instruction!
+
+ //if phi, do recursively
+ if(PHINode *p = dyn_cast<PHINode>(in)){
+ if(seenPHI[p])
+ continue;
+ else{
+ std::pair<unsigned char, unsigned char> ret =
+ getPHIRegister(p, vm, tr, seenPHI);
+ if(ret.first == 0 && ret.second == 0)
+ continue;
+ else
+ return ret;
+ }
+ }
+
+ //look if its either store or arithmetic instruction
+ if(StoreInst *stInst = dyn_cast<StoreInst>(in)){
+ vector<unsigned int> positions = getLLVMInstrPositionInfo(stInst);
+ assert(positions.size() == 1 && "More than one operand");
+
+ uint64_t addr = positions[0]*4;
+ addr += getBasicBlockInfo(stInst->getParent()).first;
+ unsigned int instr = vm->readInstrFrmVm(addr, tr);
+
+ unsigned int flags = sparc_analyze(instr);
+
+ if(flags & IF_R_RS1){
+ assert(!((flags & IF_R_RS2) | (flags & IF_R_RD)));
+ std::pair<unsigned char, unsigned char> ret =
+ std::make_pair(RD_FLD(instr, INSTR_RS1), 0);
+ if(ret.first == 0 && ret.second == 0)
+ continue;
+ else
+ return ret;
+ }
+
+ if(flags & IF_R_RS2){
+ assert(!(flags & IF_R_RD));
+ return std::make_pair(RD_FLD(instr, INSTR_RS2), 0);
+ }
+
+ if(flags & IF_R_RD)
+ return std::make_pair(RD_FLD(instr, INSTR_RD), 0);
+
+ assert(0 && "No operand for instruction");
+ }
+
+ //if arithmetic instruction, look at its operands
+ if(BinaryOperator *binop = dyn_cast<BinaryOperator>(in)){
+ vector<unsigned int> positions = getLLVMInstrPositionInfo(binop);
+
+ //check if everything matches!
+ if(positions.size() > 0){
+ uint64_t addr = positions[0]*4;
+ addr += getBasicBlockInfo(binop->getParent()).first;
+ unsigned int instr = vm->readInstrFrmVm(addr, tr);
+
+ unsigned int reg = RD_FLD(instr, INSTR_RD);
+ for(unsigned int i = 1; i < positions.size(); i++){
+ addr = positions[i]*4;
+ addr += getBasicBlockInfo(binop->getParent()).first;
+ instr = vm->readInstrFrmVm(addr, tr);
+ if(RD_FLD(instr, INSTR_RD) != reg)
+ assert(0);
+ }
+ }
+
+ uint64_t addr = positions[0]*4;
+ addr += getBasicBlockInfo(binop->getParent()).first;
+ unsigned int instr = vm->readInstrFrmVm(addr, tr);
+
+ unsigned int flags = sparc_analyze(instr);
+ assert((flags & IF_R_RS1) || (flags & IF_R_RS2) || (flags & IF_R_RD));
+
+ if((flags & IF_R_RS1) && !(flags & IF_R_RS2 || flags & IF_R_RD))
+ return std::make_pair(RD_FLD(instr, INSTR_RS1),0);
+
+ if((flags & IF_R_RS2) && !(flags & IF_R_RS1 || flags & IF_R_RD))
+ return std::make_pair(RD_FLD(instr, INSTR_RS2),0);
+
+ assert((((flags & IF_R_RS1) && (flags & IF_R_RS2)) ||
+ ((flags & IF_R_RS1) && (flags & IF_R_RD)) ||
+ ((flags & IF_R_RS2) && (flags & IF_R_RD))) &&
+ "Incorrect number of operands!");
+
+ assert(!((flags & IF_R_RS1) && (flags & IF_R_RS2) &&
+ (flags & IF_R_RD)) && "Incorrect no of operands");
+
+ if((flags & IF_R_RS1) && (flags & IF_R_RS2))
+ return std::make_pair(RD_FLD(instr, INSTR_RS1),
+ RD_FLD(instr, INSTR_RS2));
+
+ if((flags & IF_R_RS1) && (flags & IF_R_RD))
+ return std::make_pair(RD_FLD(instr, INSTR_RS1),
+ RD_FLD(instr, INSTR_RD));
+
+ if((flags & IF_R_RS2) && (flags & IF_R_RD))
+ return std::make_pair(RD_FLD(instr, INSTR_RS2),
+ RD_FLD(instr, INSTR_RD));
+ }
+ }
+ return std::make_pair(0, 0);
+}
+
+void markPHIliveOuts(vector<unsigned int> &liveout,
+ vector<BasicBlock *> &vBB,
+ map<BasicBlock *, unsigned int> &bbToCid,
+ map<BasicBlock *, unsigned char> &removedBranch,
+ PHINode *phi, VirtualMem *vm, TraceCache *tr,
+ map<PHINode *, char> &seenPHI){
+ //get all args of PHI, and see if any of them lie in the bbToCid[]
+ //(and so are in the trace).
+ //If any argument is again a PHI, call the function recursively over it
+ //The recursion would not go in a cycle because PHI nodes can not be
+ //mutually dependent on each other in a cyclical way
+ seenPHI[phi] = 1;
+
+ /*
+ std::cerr<<"------------------- bbtocid \n";
+ for(map<BasicBlock *, unsigned int>::iterator MI = bbToCid.begin(), ME =
+ bbToCid.end();
+ MI != ME; ++MI)
+ std::cerr<<MI->first;
+
+ std::cerr<<"----------------------------\n";
+ */
+
+ unsigned int n = phi->getNumIncomingValues();
+ vector<unsigned int> positions = getLLVMInstrPositionInfo(phi);
+
+ assert(positions.size() == n && "Number of incoming parameters don't match!");
+
+ for(unsigned int i = 0; i< n; i++){
+ BasicBlock *BB = phi->getIncomingBlock(i);
+ //if(bbToCid[BB]){
+ unsigned pos = positions[i];
+ if(pos == 0){
+ //look for predecessor of ith value
+ Instruction *inst = dyn_cast<Instruction>(phi->getIncomingValue(i));
+ assert(inst && "No instruction!");
+ if(PHINode *pn = dyn_cast<PHINode>(inst)){
+ if(!seenPHI[pn])
+ markPHIliveOuts(liveout, vBB, bbToCid, removedBranch, pn, vm, tr,
+ seenPHI);
+ continue;
+ }
+ BB = inst->getParent();
+ vector<unsigned int> myPositions = getLLVMInstrPositionInfo(inst);
+ pos = myPositions[myPositions.size()-1];
+ }
+ if(bbToCid[BB]){
+ if(removedBranch[BB]){
+ //get abs address
+ //if prev instr is uncond branch, this must be DS
+ uint64_t addr = getBasicBlockInfo(BB).first;
+ //get its own real address
+ addr += pos*4;
+ unsigned instr = vm->readInstrFrmVm(addr-4, tr);
+ if((removedBranch[BB] == UNCOND_BR) &&
+ (isBranchAlways(instr) || isBranchNever(instr))){
+#ifdef FOR_DEBUG
+ std::cerr<<"Marking liveout : "<<bbToCid[BB]+ pos - 1<<"\n";
+#endif
+ liveout.push_back(bbToCid[BB]+ pos - 1);
+ }
+ else if(isBranchInstr(instr) && removedBranch[BB] == CONDBR){
+#ifdef FOR_DEBUG
+ std::cerr<<"Marking liveout : "<<bbToCid[BB]+ pos-1<<"\n";
+#endif
+ liveout.push_back(bbToCid[BB]+ pos-1);
+ }
+ else{
+#ifdef FOR_DEBUG
+ std::cerr<<"Marking liveout : "<<bbToCid[BB]+ pos<<"\n";
+#endif
+ liveout.push_back(bbToCid[BB]+ pos);
+ }
+ }
+ else{
+#ifdef FOR_DEBUG
+ std::cerr<<"Marking liveout : "<<bbToCid[BB]+ pos<<"\n";
+#endif
+ liveout.push_back(bbToCid[BB] + pos);
+ }
+ }
+ }
+}
+
+void getLiveOut(vector<unsigned int> &liveout,vector<BasicBlock *> &vBB,
+ map<BasicBlock *, unsigned int> &bbToCid,
+ map<BasicBlock *, unsigned char> &removedBranch,
+ VirtualMem *vm, TraceCache *tr, BinInterface &bin){
+ //for each instruction in BB, check if it has uses
+ //if it has uses, check if any of its use has parent not in bbToCid
+ for(vector<BasicBlock *>::iterator VBI = vBB.begin(), VBE = vBB.end();
+ VBI != VBE; ++VBI){
+ //iterate over instructions
+ for(BasicBlock::iterator II = (*VBI)->begin(), IE = (*VBI)->end();
+ II != IE; ++II){
+ //iterate over all uses
+ for(Value::use_iterator UI = II->use_begin(), UE = II->use_end();
+ UI != UE; ++UI){
+ if(Instruction *in = dyn_cast<Instruction>(*UI)){
+ //see if its parent is not in bbToCid
+ if(!bbToCid[in->getParent()]){
+#ifdef FOR_DEBUG
+ std::cerr<<"Liveout instruction!\n";
+ std::cerr<<II;
+#endif
+ //find corresponding cids for II
+ if(PHINode *phi = dyn_cast<PHINode>(&*II)){
+ map<PHINode *, char> seenPHI;
+ pair<unsigned char, unsigned char> pair=
+ getPHIRegister(phi, vm, tr, seenPHI);
+ unsigned char rs1 = pair.first;
+ unsigned char rs2 = pair.second;
+
+ if(rs1 == 0 && rs2 == 0)
+ assert(0 && "Could not mark PHI as liveout");
+
+ if(rs1)
+ bin.setLiveOutReg(rs1);
+
+ if(rs2)
+ bin.setLiveOutReg(rs2);
+ }
+ else{
+ vector<unsigned int> positions = getLLVMInstrPositionInfo(II);
+
+ //mark each of them liveout
+ //for(vector<unsigned int>::iterator PI = positions.begin(),
+ // PE = positions.end(); PI != PE; ++PI){
+ //
+
+ assert(positions.size()>0);
+
+ unsigned pos = positions[positions.size()-1];//take only the last
+ //check if this BB is in removedBranch
+ if(removedBranch[*VBI]){
+ //get abs address
+ //if prev instr is uncond branch, this must be DS
+ uint64_t addr = getBasicBlockInfo(*VBI).first;
+ //get its own real address
+ addr += pos*4;
+ unsigned instr = vm->readInstrFrmVm(addr-4, tr);
+ if(isBranchAlways(instr) || isBranchNever(instr)){
+#ifdef FOR_DEBUG
+ std::cerr<<"Marking liveout non phi : "<<bbToCid[*VBI]+
+ pos-1<<"\n";
+#endif
+ liveout.push_back(bbToCid[*VBI]+ pos - 1);
+ }
+ else{
+#ifdef FOR_DEBUG
+ std::cerr<<"Marking liveout non phi : "<<bbToCid[*VBI]+
+ pos<<"\n";
+#endif
+ liveout.push_back(bbToCid[*VBI]+ pos);
+ }
+ }
+ else{
+#ifdef FOR_DEBUG
+ std::cerr<<"Marking liveout non phi : "<<bbToCid[*VBI]+
+ pos<<"\n";
+#endif
+ liveout.push_back(bbToCid[*VBI] + pos);
+ }
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+}
+
+void getPinned(vector<unsigned int> &pinned,vector<BasicBlock *> &vBB,
+ map<BasicBlock *, unsigned int> &bbToCid,
+ map<BasicBlock *, unsigned char> &removedBranch,
+ VirtualMem *vm, TraceCache *tr){
+ //iterate over ALL BBs, and then iterate over all instructions
+
+ for(vector<BasicBlock *>::iterator VBI = vBB.begin(), VBE = vBB.end();
+ VBI != VBE; ++VBI){
+ //iterate over instructions
+ for(BasicBlock::iterator II = (*VBI)->begin(), IE = (*VBI)->end();
+ II != IE; ++II){
+ if(CallInst *callInst = dyn_cast<CallInst>(&*II)){
+ //look at all the args of call inst
+ for(User::op_iterator OI = callInst->op_begin(),
+ OE = callInst->op_end();
+ OI != OE; ++OI){
+ if(Instruction *inst = dyn_cast<Instruction>((Value *)(*OI))){
+#ifdef FOR_DEBUG
+ std::cerr<<*inst;
+#endif
+ //see if it belongs to the trace
+ if(bbToCid[inst->getParent()]){
+ //get the cids for this instruction, and pin them down
+ vector<unsigned int> positions = getLLVMInstrPositionInfo(inst);
+ //mark each of them pinned
+ for(vector<unsigned int>::iterator PI = positions.begin(),
+ PE = positions.end(); PI != PE; ++PI){
+ //check if this BB is in removedBranch
+ if(removedBranch[*VBI]){
+ //get abs address
+ //if prev instr is uncond branch, this must be DS
+ uint64_t addr = getBasicBlockInfo(*VBI).first;
+ //get its own real address
+ addr += *PI*4;
+ unsigned instr = vm->readInstrFrmVm(addr-4, tr);
+ //if(isBranchAlways(instr) || isBranchNever(instr)){
+ if(isBranchInstr(instr)){
+ pinned.push_back(bbToCid[*VBI]+ *PI - 1);
+ }
+ else{
+ pinned.push_back(bbToCid[*VBI]+ *PI);
+ }
+ }
+ else{
+ pinned.push_back(bbToCid[*VBI] + *PI);
+ }
+ }
+ }
+ }
+ }
+ vector<unsigned int> positions = getLLVMInstrPositionInfo(callInst);
+ //look at all other mappings of callinst
+ for(vector<unsigned int>::iterator PI = positions.begin(),
+ PE = positions.end(); PI != PE; ++PI){
+ //check if this BB is in removedBranch
+ if(removedBranch[*VBI]){
+ //get abs address
+ //if prev instr is uncond branch, this must be DS
+ uint64_t addr = getBasicBlockInfo(*VBI).first;
+ //get its own real address
+ addr += *PI*4;
+ unsigned instr = vm->readInstrFrmVm(addr-4, tr);
+ if(isBranchAlways(instr) || isBranchNever(instr)){
+ pinned.push_back(bbToCid[*VBI]+ *PI - 1);
+ }
+ else{
+ pinned.push_back(bbToCid[*VBI]+ *PI);
+ }
+ }
+ else{
+ pinned.push_back(bbToCid[*VBI] + *PI);
+ }
+ }
+ }
+ }
+ }
+}
+
+bool isThrashing(TraceCache *tr, uint64_t startAddr){
+ //Keep count of thrashing, so as to avoid it!
+ static std::map<uint64_t, int> thrashing;
+
+ if(tr->hasTraceAddr(startAddr) && thrashing[startAddr]<4){
+ thrashing[startAddr] += 1;
+ tr->removeTrace(startAddr);
+ }
+ else if(thrashing[startAddr] > 3){
+ return true;
+ }
+ return false;
+}
+
+Module *initModules(vector<Function *> &funcList){
+ Module *M;
+#ifdef READER_TIME
+ cpc_count_usr_events(1);
+#endif
+ //BytecodeParser Parser;
+ std::string err;
+ M = ParseBytecodeBuffer(LLVMBytecode, llvm_length, "NOFILENAME", &err);
+#ifdef READER_TIME
+ cpc_count_usr_events(0);
+#endif
+ assert(M && "Module parsing failed!");
+
+ //read in pointers to functions
+ int mmn = -1;
+ for(Module::iterator MI=M->begin(), ME=M->end(); MI!=ME; MI++){
+ Function *F = MI;
+
+ if(F->isExternal()) {
+ continue;
+ }
+
+ mmn++;
+ funcList.push_back(F);
+ }
+ return M;
+}
+
+bool isWellFormedLoop(vector<BasicBlock *> &vBB, Function *f){
+ if(vBB[0] == &f->front() ||
+ isa<ReturnInst>(vBB[vBB.size()-1]->getTerminator())){
+ //Found a path starting with root
+ return false;
+ }
+
+ //check if loop is not formed
+ TerminatorInst *Tcheck = vBB[vBB.size()-1]->getTerminator();
+ BranchInst *Bcheck = cast<BranchInst>(Tcheck);
+ if(Bcheck->isConditional()){
+ if((vBB[0] != Bcheck->getSuccessor(0)) &&
+ (vBB[0] != Bcheck->getSuccessor(1))){
+ //std::cerr<<"llvm:: Not a loop!\n";
+ return false;
+ }
+ }
+ else{
+ if(vBB[0] != Bcheck->getSuccessor(0)){
+ //std::cerr<<"llvm:: Not a loop!\n";
+ return false;
+ }
+ }
+ return true;
+}
More information about the llvm-commits
mailing list