MSchedGraphSB.cpp 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870
  1. //===-- MSchedGraphSB.cpp - Scheduling Graph ----------------------*- C++ -*-===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file was developed by the LLVM research group and is distributed under
  6. // the University of Illinois Open Source License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // A graph class for dependencies. This graph only contains true, anti, and
  11. // output data dependencies for a given MachineBasicBlock. Dependencies
  12. // across iterations are also computed. Unless data dependence analysis
  13. // is provided, a conservative approach of adding dependencies between all
  14. // loads and stores is taken.
  15. //===----------------------------------------------------------------------===//
  16. #define DEBUG_TYPE "ModuloSchedSB"
  17. #include "MSchedGraphSB.h"
  18. #include "../SparcV9RegisterInfo.h"
  19. #include "../MachineCodeForInstruction.h"
  20. #include "llvm/BasicBlock.h"
  21. #include "llvm/Constants.h"
  22. #include "llvm/Instructions.h"
  23. #include "llvm/Type.h"
  24. #include "llvm/CodeGen/MachineBasicBlock.h"
  25. #include "llvm/Target/TargetInstrInfo.h"
  26. #include "llvm/Support/Debug.h"
  27. #include <cstdlib>
  28. #include <algorithm>
  29. #include <set>
  30. #include "llvm/Target/TargetSchedInfo.h"
  31. #include "../SparcV9Internals.h"
  32. using namespace llvm;
  33. //MSchedGraphSBNode constructor
  34. MSchedGraphSBNode::MSchedGraphSBNode(const MachineInstr* inst,
  35. MSchedGraphSB *graph, unsigned idx,
  36. unsigned late, bool isBranch)
  37. : Inst(inst), Parent(graph), index(idx), latency(late),
  38. isBranchInstr(isBranch) {
  39. //Add to the graph
  40. graph->addNode(inst, this);
  41. }
  42. //MSchedGraphSBNode constructor
  43. MSchedGraphSBNode::MSchedGraphSBNode(const MachineInstr* inst,
  44. std::vector<const MachineInstr*> &other,
  45. MSchedGraphSB *graph, unsigned idx,
  46. unsigned late, bool isPNode)
  47. : Inst(inst), otherInstrs(other), Parent(graph), index(idx), latency(late), isPredicateNode(isPNode) {
  48. isBranchInstr = false;
  49. //Add to the graph
  50. graph->addNode(inst, this);
  51. }
  52. //MSchedGraphSBNode copy constructor
  53. MSchedGraphSBNode::MSchedGraphSBNode(const MSchedGraphSBNode &N)
  54. : Predecessors(N.Predecessors), Successors(N.Successors) {
  55. Inst = N.Inst;
  56. Parent = N.Parent;
  57. index = N.index;
  58. latency = N.latency;
  59. isBranchInstr = N.isBranchInstr;
  60. otherInstrs = N.otherInstrs;
  61. }
  62. //Print the node (instruction and latency)
  63. void MSchedGraphSBNode::print(std::ostream &os) const {
  64. if(!isPredicate())
  65. os << "MSchedGraphSBNode: Inst=" << *Inst << ", latency= " << latency << "\n";
  66. else
  67. os << "Pred Node\n";
  68. }
  69. //Get the edge from a predecessor to this node
  70. MSchedGraphSBEdge MSchedGraphSBNode::getInEdge(MSchedGraphSBNode *pred) {
  71. //Loop over all the successors of our predecessor
  72. //return the edge the corresponds to this in edge
  73. for (MSchedGraphSBNode::succ_iterator I = pred->succ_begin(),
  74. E = pred->succ_end(); I != E; ++I) {
  75. if (*I == this)
  76. return I.getEdge();
  77. }
  78. assert(0 && "Should have found edge between this node and its predecessor!");
  79. abort();
  80. }
  81. //Get the iteration difference for the edge from this node to its successor
  82. unsigned MSchedGraphSBNode::getIteDiff(MSchedGraphSBNode *succ) {
  83. for(std::vector<MSchedGraphSBEdge>::iterator I = Successors.begin(),
  84. E = Successors.end();
  85. I != E; ++I) {
  86. if(I->getDest() == succ)
  87. return I->getIteDiff();
  88. }
  89. return 0;
  90. }
  91. //Get the index into the vector of edges for the edge from pred to this node
  92. unsigned MSchedGraphSBNode::getInEdgeNum(MSchedGraphSBNode *pred) {
  93. //Loop over all the successors of our predecessor
  94. //return the edge the corresponds to this in edge
  95. int count = 0;
  96. for(MSchedGraphSBNode::succ_iterator I = pred->succ_begin(),
  97. E = pred->succ_end();
  98. I != E; ++I) {
  99. if(*I == this)
  100. return count;
  101. count++;
  102. }
  103. assert(0 && "Should have found edge between this node and its predecessor!");
  104. abort();
  105. }
  106. //Determine if succ is a successor of this node
  107. bool MSchedGraphSBNode::isSuccessor(MSchedGraphSBNode *succ) {
  108. for(succ_iterator I = succ_begin(), E = succ_end(); I != E; ++I)
  109. if(*I == succ)
  110. return true;
  111. return false;
  112. }
  113. //Dtermine if pred is a predecessor of this node
  114. bool MSchedGraphSBNode::isPredecessor(MSchedGraphSBNode *pred) {
  115. if(std::find( Predecessors.begin(), Predecessors.end(),
  116. pred) != Predecessors.end())
  117. return true;
  118. else
  119. return false;
  120. }
  121. //Add a node to the graph
  122. void MSchedGraphSB::addNode(const MachineInstr* MI,
  123. MSchedGraphSBNode *node) {
  124. //Make sure node does not already exist
  125. assert(GraphMap.find(MI) == GraphMap.end()
  126. && "New MSchedGraphSBNode already exists for this instruction");
  127. GraphMap[MI] = node;
  128. }
  129. //Delete a node to the graph
  130. void MSchedGraphSB::deleteNode(MSchedGraphSBNode *node) {
  131. //Delete the edge to this node from all predecessors
  132. while(node->pred_size() > 0) {
  133. //DEBUG(std::cerr << "Delete edge from: " << **P << " to " << *node << "\n");
  134. MSchedGraphSBNode *pred = *(node->pred_begin());
  135. pred->deleteSuccessor(node);
  136. }
  137. //Remove this node from the graph
  138. GraphMap.erase(node->getInst());
  139. }
  140. //Create a graph for a machine block. The ignoreInstrs map is so that
  141. //we ignore instructions associated to the index variable since this
  142. //is a special case in Modulo Scheduling. We only want to deal with
  143. //the body of the loop.
  144. MSchedGraphSB::MSchedGraphSB(std::vector<const MachineBasicBlock*> &bbs,
  145. const TargetMachine &targ,
  146. std::map<const MachineInstr*, unsigned> &ignoreInstrs,
  147. DependenceAnalyzer &DA,
  148. std::map<MachineInstr*, Instruction*> &machineTollvm)
  149. : BBs(bbs), Target(targ) {
  150. //Make sure there is at least one BB and it is not null,
  151. assert(((bbs.size() >= 1) && bbs[1] != NULL) && "Basic Block is null");
  152. std::map<MSchedGraphSBNode*, std::set<MachineInstr*> > liveOutsideTrace;
  153. std::set<const BasicBlock*> llvmBBs;
  154. for(std::vector<const MachineBasicBlock*>::iterator MBB = bbs.begin(), ME = bbs.end()-1;
  155. MBB != ME; ++MBB)
  156. llvmBBs.insert((*MBB)->getBasicBlock());
  157. //create predicate nodes
  158. DEBUG(std::cerr << "Create predicate nodes\n");
  159. for(std::vector<const MachineBasicBlock*>::iterator MBB = bbs.begin(), ME = bbs.end()-1;
  160. MBB != ME; ++MBB) {
  161. //Get LLVM basic block
  162. BasicBlock *BB = (BasicBlock*) (*MBB)->getBasicBlock();
  163. //Get Terminator
  164. BranchInst *b = dyn_cast<BranchInst>(BB->getTerminator());
  165. std::vector<const MachineInstr*> otherInstrs;
  166. MachineInstr *instr = 0;
  167. //Get the condition for the branch (we already checked if it was conditional)
  168. if(b->isConditional()) {
  169. Value *cond = b->getCondition();
  170. DEBUG(std::cerr << "Condition: " << *cond << "\n");
  171. assert(cond && "Condition must not be null!");
  172. if(Instruction *I = dyn_cast<Instruction>(cond)) {
  173. MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(I);
  174. if(tempMvec.size() > 0) {
  175. DEBUG(std::cerr << *(tempMvec[tempMvec.size()-1]) << "\n");;
  176. instr = (MachineInstr*) tempMvec[tempMvec.size()-1];
  177. }
  178. }
  179. }
  180. //Get Machine target information for calculating latency
  181. const TargetInstrInfo *MTI = Target.getInstrInfo();
  182. MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(b);
  183. int offset = tempMvec.size();
  184. for (unsigned j = 0; j < tempMvec.size(); j++) {
  185. MachineInstr *mi = tempMvec[j];
  186. if(MTI->isNop(mi->getOpcode()))
  187. continue;
  188. if(!instr) {
  189. instr = mi;
  190. DEBUG(std::cerr << "No Cond MI: " << *mi << "\n");
  191. }
  192. else {
  193. DEBUG(std::cerr << *mi << "\n");;
  194. otherInstrs.push_back(mi);
  195. }
  196. }
  197. //Node is created and added to the graph automatically
  198. MSchedGraphSBNode *node = new MSchedGraphSBNode(instr, otherInstrs, this, (*MBB)->size()-offset-1, 3, true);
  199. DEBUG(std::cerr << "Created Node: " << *node << "\n");
  200. //Now loop over all instructions and see if their def is live outside the trace
  201. MachineBasicBlock *mb = (MachineBasicBlock*) *MBB;
  202. for(MachineBasicBlock::iterator I = mb->begin(), E = mb->end(); I != E; ++I) {
  203. MachineInstr *instr = I;
  204. if(MTI->isNop(instr->getOpcode()) || MTI->isBranch(instr->getOpcode()))
  205. continue;
  206. if(node->getInst() == instr)
  207. continue;
  208. for(unsigned i=0; i < instr->getNumOperands(); ++i) {
  209. MachineOperand &mOp = instr->getOperand(i);
  210. if(mOp.isDef() && mOp.getType() == MachineOperand::MO_VirtualRegister) {
  211. Value *val = mOp.getVRegValue();
  212. //Check if there is a use not in the trace
  213. for(Value::use_iterator V = val->use_begin(), VE = val->use_end(); V != VE; ++V) {
  214. if (Instruction *Inst = dyn_cast<Instruction>(*V)) {
  215. if(llvmBBs.count(Inst->getParent()))
  216. liveOutsideTrace[node].insert(instr);
  217. }
  218. }
  219. }
  220. }
  221. }
  222. }
  223. //Create nodes and edges for this BB
  224. buildNodesAndEdges(ignoreInstrs, DA, machineTollvm, liveOutsideTrace);
  225. }
  226. //Copies the graph and keeps a map from old to new nodes
  227. MSchedGraphSB::MSchedGraphSB(const MSchedGraphSB &G,
  228. std::map<MSchedGraphSBNode*, MSchedGraphSBNode*> &newNodes)
  229. : Target(G.Target) {
  230. BBs = G.BBs;
  231. std::map<MSchedGraphSBNode*, MSchedGraphSBNode*> oldToNew;
  232. //Copy all nodes
  233. for(MSchedGraphSB::const_iterator N = G.GraphMap.begin(),
  234. NE = G.GraphMap.end(); N != NE; ++N) {
  235. MSchedGraphSBNode *newNode = new MSchedGraphSBNode(*(N->second));
  236. oldToNew[&*(N->second)] = newNode;
  237. newNodes[newNode] = &*(N->second);
  238. GraphMap[&*(N->first)] = newNode;
  239. }
  240. //Loop over nodes and update edges to point to new nodes
  241. for(MSchedGraphSB::iterator N = GraphMap.begin(), NE = GraphMap.end();
  242. N != NE; ++N) {
  243. //Get the node we are dealing with
  244. MSchedGraphSBNode *node = &*(N->second);
  245. node->setParent(this);
  246. //Loop over nodes successors and predecessors and update to the new nodes
  247. for(unsigned i = 0; i < node->pred_size(); ++i) {
  248. node->setPredecessor(i, oldToNew[node->getPredecessor(i)]);
  249. }
  250. for(unsigned i = 0; i < node->succ_size(); ++i) {
  251. MSchedGraphSBEdge *edge = node->getSuccessor(i);
  252. MSchedGraphSBNode *oldDest = edge->getDest();
  253. edge->setDest(oldToNew[oldDest]);
  254. }
  255. }
  256. }
  257. //Deconstructor, deletes all nodes in the graph
  258. MSchedGraphSB::~MSchedGraphSB () {
  259. for(MSchedGraphSB::iterator I = GraphMap.begin(), E = GraphMap.end();
  260. I != E; ++I)
  261. delete I->second;
  262. }
  263. //Print out graph
  264. void MSchedGraphSB::print(std::ostream &os) const {
  265. for(MSchedGraphSB::const_iterator N = GraphMap.begin(), NE = GraphMap.end();
  266. N != NE; ++N) {
  267. //Get the node we are dealing with
  268. MSchedGraphSBNode *node = &*(N->second);
  269. os << "Node Start\n";
  270. node->print(os);
  271. os << "Successors:\n";
  272. //print successors
  273. for(unsigned i = 0; i < node->succ_size(); ++i) {
  274. MSchedGraphSBEdge *edge = node->getSuccessor(i);
  275. MSchedGraphSBNode *oldDest = edge->getDest();
  276. oldDest->print(os);
  277. }
  278. os << "Node End\n";
  279. }
  280. }
  281. //Calculate total delay
  282. int MSchedGraphSB::totalDelay() {
  283. int sum = 0;
  284. for(MSchedGraphSB::const_iterator N = GraphMap.begin(), NE = GraphMap.end();
  285. N != NE; ++N) {
  286. //Get the node we are dealing with
  287. MSchedGraphSBNode *node = &*(N->second);
  288. sum += node->getLatency();
  289. }
  290. return sum;
  291. }
  292. bool MSchedGraphSB::instrCauseException(MachineOpCode opCode) {
  293. //Check for integer divide
  294. if(opCode == V9::SDIVXr || opCode == V9::SDIVXi
  295. || opCode == V9::UDIVXr || opCode == V9::UDIVXi)
  296. return true;
  297. //Check for loads or stores
  298. const TargetInstrInfo *MTI = Target.getInstrInfo();
  299. //if( MTI->isLoad(opCode) ||
  300. if(MTI->isStore(opCode))
  301. return true;
  302. //Check for any floating point operation
  303. const TargetSchedInfo *msi = Target.getSchedInfo();
  304. InstrSchedClass sc = msi->getSchedClass(opCode);
  305. //FIXME: Should check for floating point instructions!
  306. //if(sc == SPARC_FGA || sc == SPARC_FGM)
  307. //return true;
  308. return false;
  309. }
  310. //Add edges between the nodes
  311. void MSchedGraphSB::buildNodesAndEdges(std::map<const MachineInstr*, unsigned> &ignoreInstrs,
  312. DependenceAnalyzer &DA,
  313. std::map<MachineInstr*, Instruction*> &machineTollvm,
  314. std::map<MSchedGraphSBNode*, std::set<MachineInstr*> > &liveOutsideTrace) {
  315. //Get Machine target information for calculating latency
  316. const TargetInstrInfo *MTI = Target.getInstrInfo();
  317. std::vector<MSchedGraphSBNode*> memInstructions;
  318. std::map<int, std::vector<OpIndexNodePair> > regNumtoNodeMap;
  319. std::map<const Value*, std::vector<OpIndexNodePair> > valuetoNodeMap;
  320. //Save PHI instructions to deal with later
  321. std::vector<const MachineInstr*> phiInstrs;
  322. unsigned index = 0;
  323. MSchedGraphSBNode *lastPred = 0;
  324. for(std::vector<const MachineBasicBlock*>::iterator B = BBs.begin(),
  325. BE = BBs.end(); B != BE; ++B) {
  326. const MachineBasicBlock *BB = *B;
  327. //Loop over instructions in MBB and add nodes and edges
  328. for (MachineBasicBlock::const_iterator MI = BB->begin(), e = BB->end();
  329. MI != e; ++MI) {
  330. //Ignore indvar instructions
  331. if(ignoreInstrs.count(MI)) {
  332. ++index;
  333. continue;
  334. }
  335. //Get each instruction of machine basic block, get the delay
  336. //using the op code, create a new node for it, and add to the
  337. //graph.
  338. MachineOpCode opCode = MI->getOpcode();
  339. int delay;
  340. //Get delay
  341. delay = MTI->maxLatency(opCode);
  342. //Create new node for this machine instruction and add to the graph.
  343. //Create only if not a nop
  344. if(MTI->isNop(opCode))
  345. continue;
  346. //Sparc BE does not use PHI opcode, so assert on this case
  347. assert(opCode != TargetInstrInfo::PHI && "Did not expect PHI opcode");
  348. bool isBranch = false;
  349. //Skip branches
  350. if(MTI->isBranch(opCode))
  351. continue;
  352. //Node is created and added to the graph automatically
  353. MSchedGraphSBNode *node = 0;
  354. if(!GraphMap.count(MI)){
  355. node = new MSchedGraphSBNode(MI, this, index, delay);
  356. DEBUG(std::cerr << "Created Node: " << *node << "\n");
  357. }
  358. else {
  359. node = GraphMap[MI];
  360. if(node->isPredicate()) {
  361. //Create edge between this node and last pred, then switch to new pred
  362. if(lastPred) {
  363. lastPred->addOutEdge(node, MSchedGraphSBEdge::PredDep,
  364. MSchedGraphSBEdge::NonDataDep, 0);
  365. if(liveOutsideTrace.count(lastPred)) {
  366. for(std::set<MachineInstr*>::iterator L = liveOutsideTrace[lastPred].begin(), LE = liveOutsideTrace[lastPred].end(); L != LE; ++L)
  367. lastPred->addOutEdge(GraphMap[*L], MSchedGraphSBEdge::PredDep,
  368. MSchedGraphSBEdge::NonDataDep, 1);
  369. }
  370. }
  371. lastPred = node;
  372. }
  373. }
  374. //Add dependencies to instructions that cause exceptions
  375. if(lastPred)
  376. lastPred->print(std::cerr);
  377. if(!node->isPredicate() && instrCauseException(opCode)) {
  378. if(lastPred) {
  379. lastPred->addOutEdge(node, MSchedGraphSBEdge::PredDep,
  380. MSchedGraphSBEdge::NonDataDep, 0);
  381. }
  382. }
  383. //Check OpCode to keep track of memory operations to add memory
  384. //dependencies later.
  385. if(MTI->isLoad(opCode) || MTI->isStore(opCode))
  386. memInstructions.push_back(node);
  387. //Loop over all operands, and put them into the register number to
  388. //graph node map for determining dependencies
  389. //If an operands is a use/def, we have an anti dependence to itself
  390. for(unsigned i=0; i < MI->getNumOperands(); ++i) {
  391. //Get Operand
  392. const MachineOperand &mOp = MI->getOperand(i);
  393. //Check if it has an allocated register
  394. if(mOp.hasAllocatedReg()) {
  395. int regNum = mOp.getReg();
  396. if(regNum != SparcV9::g0) {
  397. //Put into our map
  398. regNumtoNodeMap[regNum].push_back(std::make_pair(i, node));
  399. }
  400. continue;
  401. }
  402. //Add virtual registers dependencies
  403. //Check if any exist in the value map already and create dependencies
  404. //between them.
  405. if(mOp.getType() == MachineOperand::MO_VirtualRegister
  406. || mOp.getType() == MachineOperand::MO_CCRegister) {
  407. //Make sure virtual register value is not null
  408. assert((mOp.getVRegValue() != NULL) && "Null value is defined");
  409. //Check if this is a read operation in a phi node, if so DO NOT PROCESS
  410. if(mOp.isUse() && (opCode == TargetInstrInfo::PHI)) {
  411. DEBUG(std::cerr << "Read Operation in a PHI node\n");
  412. continue;
  413. }
  414. if (const Value* srcI = mOp.getVRegValue()) {
  415. //Find value in the map
  416. std::map<const Value*, std::vector<OpIndexNodePair> >::iterator V
  417. = valuetoNodeMap.find(srcI);
  418. //If there is something in the map already, add edges from
  419. //those instructions
  420. //to this one we are processing
  421. if(V != valuetoNodeMap.end()) {
  422. addValueEdges(V->second, node, mOp.isUse(), mOp.isDef(), phiInstrs);
  423. //Add to value map
  424. V->second.push_back(std::make_pair(i,node));
  425. }
  426. //Otherwise put it in the map
  427. else
  428. //Put into value map
  429. valuetoNodeMap[mOp.getVRegValue()].push_back(std::make_pair(i, node));
  430. }
  431. }
  432. }
  433. ++index;
  434. }
  435. //Loop over LLVM BB, examine phi instructions, and add them to our
  436. //phiInstr list to process
  437. const BasicBlock *llvm_bb = BB->getBasicBlock();
  438. for(BasicBlock::const_iterator I = llvm_bb->begin(), E = llvm_bb->end();
  439. I != E; ++I) {
  440. if(const PHINode *PN = dyn_cast<PHINode>(I)) {
  441. MachineCodeForInstruction & tempMvec = MachineCodeForInstruction::get(PN);
  442. for (unsigned j = 0; j < tempMvec.size(); j++) {
  443. if(!ignoreInstrs.count(tempMvec[j])) {
  444. DEBUG(std::cerr << "Inserting phi instr into map: " << *tempMvec[j] << "\n");
  445. phiInstrs.push_back((MachineInstr*) tempMvec[j]);
  446. }
  447. }
  448. }
  449. }
  450. addMemEdges(memInstructions, DA, machineTollvm);
  451. addMachRegEdges(regNumtoNodeMap);
  452. //Finally deal with PHI Nodes and Value*
  453. for(std::vector<const MachineInstr*>::iterator I = phiInstrs.begin(),
  454. E = phiInstrs.end(); I != E; ++I) {
  455. //Get Node for this instruction
  456. std::map<const MachineInstr*, MSchedGraphSBNode*>::iterator X;
  457. X = find(*I);
  458. if(X == GraphMap.end())
  459. continue;
  460. MSchedGraphSBNode *node = X->second;
  461. DEBUG(std::cerr << "Adding ite diff edges for node: " << *node << "\n");
  462. //Loop over operands for this instruction and add value edges
  463. for(unsigned i=0; i < (*I)->getNumOperands(); ++i) {
  464. //Get Operand
  465. const MachineOperand &mOp = (*I)->getOperand(i);
  466. if((mOp.getType() == MachineOperand::MO_VirtualRegister
  467. || mOp.getType() == MachineOperand::MO_CCRegister) && mOp.isUse()) {
  468. //find the value in the map
  469. if (const Value* srcI = mOp.getVRegValue()) {
  470. //Find value in the map
  471. std::map<const Value*, std::vector<OpIndexNodePair> >::iterator V
  472. = valuetoNodeMap.find(srcI);
  473. //If there is something in the map already, add edges from
  474. //those instructions
  475. //to this one we are processing
  476. if(V != valuetoNodeMap.end()) {
  477. addValueEdges(V->second, node, mOp.isUse(), mOp.isDef(),
  478. phiInstrs, 1);
  479. }
  480. }
  481. }
  482. }
  483. }
  484. }
  485. }
  486. //Add dependencies for Value*s
  487. void MSchedGraphSB::addValueEdges(std::vector<OpIndexNodePair> &NodesInMap,
  488. MSchedGraphSBNode *destNode, bool nodeIsUse,
  489. bool nodeIsDef, std::vector<const MachineInstr*> &phiInstrs, int diff) {
  490. for(std::vector<OpIndexNodePair>::iterator I = NodesInMap.begin(),
  491. E = NodesInMap.end(); I != E; ++I) {
  492. //Get node in vectors machine operand that is the same value as node
  493. MSchedGraphSBNode *srcNode = I->second;
  494. MachineOperand mOp = srcNode->getInst()->getOperand(I->first);
  495. if(diff > 0)
  496. if(std::find(phiInstrs.begin(), phiInstrs.end(), srcNode->getInst()) == phiInstrs.end())
  497. continue;
  498. //Node is a Def, so add output dep.
  499. if(nodeIsDef) {
  500. if(mOp.isUse()) {
  501. DEBUG(std::cerr << "Edge from " << *srcNode << " to " << *destNode << " (itediff=" << diff << ", type=anti)\n");
  502. srcNode->addOutEdge(destNode, MSchedGraphSBEdge::ValueDep,
  503. MSchedGraphSBEdge::AntiDep, diff);
  504. }
  505. if(mOp.isDef()) {
  506. DEBUG(std::cerr << "Edge from " << *srcNode << " to " << *destNode << " (itediff=" << diff << ", type=output)\n");
  507. srcNode->addOutEdge(destNode, MSchedGraphSBEdge::ValueDep,
  508. MSchedGraphSBEdge::OutputDep, diff);
  509. }
  510. }
  511. if(nodeIsUse) {
  512. if(mOp.isDef()) {
  513. DEBUG(std::cerr << "Edge from " << *srcNode << " to " << *destNode << " (itediff=" << diff << ", type=true)\n");
  514. srcNode->addOutEdge(destNode, MSchedGraphSBEdge::ValueDep,
  515. MSchedGraphSBEdge::TrueDep, diff);
  516. }
  517. }
  518. }
  519. }
  520. //Add dependencies for machine registers across iterations
  521. void MSchedGraphSB::addMachRegEdges(std::map<int, std::vector<OpIndexNodePair> >& regNumtoNodeMap) {
  522. //Loop over all machine registers in the map, and add dependencies
  523. //between the instructions that use it
  524. typedef std::map<int, std::vector<OpIndexNodePair> > regNodeMap;
  525. for(regNodeMap::iterator I = regNumtoNodeMap.begin();
  526. I != regNumtoNodeMap.end(); ++I) {
  527. //Get the register number
  528. int regNum = (*I).first;
  529. //Get Vector of nodes that use this register
  530. std::vector<OpIndexNodePair> Nodes = (*I).second;
  531. //Loop over nodes and determine the dependence between the other
  532. //nodes in the vector
  533. for(unsigned i =0; i < Nodes.size(); ++i) {
  534. //Get src node operator index that uses this machine register
  535. int srcOpIndex = Nodes[i].first;
  536. //Get the actual src Node
  537. MSchedGraphSBNode *srcNode = Nodes[i].second;
  538. //Get Operand
  539. const MachineOperand &srcMOp = srcNode->getInst()->getOperand(srcOpIndex);
  540. bool srcIsUseandDef = srcMOp.isDef() && srcMOp.isUse();
  541. bool srcIsUse = srcMOp.isUse() && !srcMOp.isDef();
  542. //Look at all instructions after this in execution order
  543. for(unsigned j=i+1; j < Nodes.size(); ++j) {
  544. //Sink node is a write
  545. if(Nodes[j].second->getInst()->getOperand(Nodes[j].first).isDef()) {
  546. //Src only uses the register (read)
  547. if(srcIsUse)
  548. srcNode->addOutEdge(Nodes[j].second,
  549. MSchedGraphSBEdge::MachineRegister,
  550. MSchedGraphSBEdge::AntiDep);
  551. else if(srcIsUseandDef) {
  552. srcNode->addOutEdge(Nodes[j].second,
  553. MSchedGraphSBEdge::MachineRegister,
  554. MSchedGraphSBEdge::AntiDep);
  555. srcNode->addOutEdge(Nodes[j].second,
  556. MSchedGraphSBEdge::MachineRegister,
  557. MSchedGraphSBEdge::OutputDep);
  558. }
  559. else
  560. srcNode->addOutEdge(Nodes[j].second,
  561. MSchedGraphSBEdge::MachineRegister,
  562. MSchedGraphSBEdge::OutputDep);
  563. }
  564. //Dest node is a read
  565. else {
  566. if(!srcIsUse || srcIsUseandDef)
  567. srcNode->addOutEdge(Nodes[j].second,
  568. MSchedGraphSBEdge::MachineRegister,
  569. MSchedGraphSBEdge::TrueDep);
  570. }
  571. }
  572. //Look at all the instructions before this one since machine registers
  573. //could live across iterations.
  574. for(unsigned j = 0; j < i; ++j) {
  575. //Sink node is a write
  576. if(Nodes[j].second->getInst()->getOperand(Nodes[j].first).isDef()) {
  577. //Src only uses the register (read)
  578. if(srcIsUse)
  579. srcNode->addOutEdge(Nodes[j].second,
  580. MSchedGraphSBEdge::MachineRegister,
  581. MSchedGraphSBEdge::AntiDep, 1);
  582. else if(srcIsUseandDef) {
  583. srcNode->addOutEdge(Nodes[j].second,
  584. MSchedGraphSBEdge::MachineRegister,
  585. MSchedGraphSBEdge::AntiDep, 1);
  586. srcNode->addOutEdge(Nodes[j].second,
  587. MSchedGraphSBEdge::MachineRegister,
  588. MSchedGraphSBEdge::OutputDep, 1);
  589. }
  590. else
  591. srcNode->addOutEdge(Nodes[j].second,
  592. MSchedGraphSBEdge::MachineRegister,
  593. MSchedGraphSBEdge::OutputDep, 1);
  594. }
  595. //Dest node is a read
  596. else {
  597. if(!srcIsUse || srcIsUseandDef)
  598. srcNode->addOutEdge(Nodes[j].second,
  599. MSchedGraphSBEdge::MachineRegister,
  600. MSchedGraphSBEdge::TrueDep,1 );
  601. }
  602. }
  603. }
  604. }
  605. }
  606. //Add edges between all loads and stores
  607. //Can be less strict with alias analysis and data dependence analysis.
  608. void MSchedGraphSB::addMemEdges(const std::vector<MSchedGraphSBNode*>& memInst,
  609. DependenceAnalyzer &DA,
  610. std::map<MachineInstr*, Instruction*> &machineTollvm) {
  611. //Get Target machine instruction info
  612. const TargetInstrInfo *TMI = Target.getInstrInfo();
  613. //Loop over all memory instructions in the vector
  614. //Knowing that they are in execution, add true, anti, and output dependencies
  615. for (unsigned srcIndex = 0; srcIndex < memInst.size(); ++srcIndex) {
  616. MachineInstr *srcInst = (MachineInstr*) memInst[srcIndex]->getInst();
  617. //Get the machine opCode to determine type of memory instruction
  618. MachineOpCode srcNodeOpCode = srcInst->getOpcode();
  619. //All instructions after this one in execution order have an
  620. //iteration delay of 0
  621. for(unsigned destIndex = 0; destIndex < memInst.size(); ++destIndex) {
  622. //No self loops
  623. if(destIndex == srcIndex)
  624. continue;
  625. MachineInstr *destInst = (MachineInstr*) memInst[destIndex]->getInst();
  626. DEBUG(std::cerr << "MInst1: " << *srcInst << "\n");
  627. DEBUG(std::cerr << "MInst2: " << *destInst << "\n");
  628. //Assuming instructions without corresponding llvm instructions
  629. //are from constant pools.
  630. if (!machineTollvm.count(srcInst) || !machineTollvm.count(destInst))
  631. continue;
  632. bool useDepAnalyzer = true;
  633. //Some machine loads and stores are generated by casts, so be
  634. //conservative and always add deps
  635. Instruction *srcLLVM = machineTollvm[srcInst];
  636. Instruction *destLLVM = machineTollvm[destInst];
  637. if(!isa<LoadInst>(srcLLVM)
  638. && !isa<StoreInst>(srcLLVM)) {
  639. if(isa<BinaryOperator>(srcLLVM)) {
  640. if(isa<ConstantFP>(srcLLVM->getOperand(0)) || isa<ConstantFP>(srcLLVM->getOperand(1)))
  641. continue;
  642. }
  643. useDepAnalyzer = false;
  644. }
  645. if(!isa<LoadInst>(destLLVM)
  646. && !isa<StoreInst>(destLLVM)) {
  647. if(isa<BinaryOperator>(destLLVM)) {
  648. if(isa<ConstantFP>(destLLVM->getOperand(0)) || isa<ConstantFP>(destLLVM->getOperand(1)))
  649. continue;
  650. }
  651. useDepAnalyzer = false;
  652. }
  653. //Use dep analysis when we have corresponding llvm loads/stores
  654. if(useDepAnalyzer) {
  655. bool srcBeforeDest = true;
  656. if(destIndex < srcIndex)
  657. srcBeforeDest = false;
  658. DependenceResult dr = DA.getDependenceInfo(machineTollvm[srcInst],
  659. machineTollvm[destInst],
  660. srcBeforeDest);
  661. for(std::vector<Dependence>::iterator d = dr.dependences.begin(),
  662. de = dr.dependences.end(); d != de; ++d) {
  663. //Add edge from load to store
  664. memInst[srcIndex]->addOutEdge(memInst[destIndex],
  665. MSchedGraphSBEdge::MemoryDep,
  666. d->getDepType(), d->getIteDiff());
  667. }
  668. }
  669. //Otherwise, we can not do any further analysis and must make a dependence
  670. else {
  671. //Get the machine opCode to determine type of memory instruction
  672. MachineOpCode destNodeOpCode = destInst->getOpcode();
  673. //Get the Value* that we are reading from the load, always the first op
  674. const MachineOperand &mOp = srcInst->getOperand(0);
  675. const MachineOperand &mOp2 = destInst->getOperand(0);
  676. if(mOp.hasAllocatedReg())
  677. if(mOp.getReg() == SparcV9::g0)
  678. continue;
  679. if(mOp2.hasAllocatedReg())
  680. if(mOp2.getReg() == SparcV9::g0)
  681. continue;
  682. DEBUG(std::cerr << "Adding dependence for machine instructions\n");
  683. //Load-Store deps
  684. if(TMI->isLoad(srcNodeOpCode)) {
  685. if(TMI->isStore(destNodeOpCode))
  686. memInst[srcIndex]->addOutEdge(memInst[destIndex],
  687. MSchedGraphSBEdge::MemoryDep,
  688. MSchedGraphSBEdge::AntiDep, 0);
  689. }
  690. else if(TMI->isStore(srcNodeOpCode)) {
  691. if(TMI->isStore(destNodeOpCode))
  692. memInst[srcIndex]->addOutEdge(memInst[destIndex],
  693. MSchedGraphSBEdge::MemoryDep,
  694. MSchedGraphSBEdge::OutputDep, 0);
  695. else
  696. memInst[srcIndex]->addOutEdge(memInst[destIndex],
  697. MSchedGraphSBEdge::MemoryDep,
  698. MSchedGraphSBEdge::TrueDep, 0);
  699. }
  700. }
  701. }
  702. }
  703. }