llvm.org GIT mirror llvm / efbcebc
Sketch out an implementation of Briggs' copy placement algorithm. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@45334 91177308-0d34-0410-b5e6-96231b3b80d8 Owen Anderson 12 years ago
1 changed file(s) with 104 addition(s) and 10 deletion(s). Raw diff Collapse all Expand all
2727 #include "llvm/CodeGen/SSARegMap.h"
2828 #include "llvm/Target/TargetInstrInfo.h"
2929 #include "llvm/Target/TargetMachine.h"
30 #include "llvm/ADT/DepthFirstIterator.h"
3031 #include "llvm/ADT/Statistic.h"
3132 #include "llvm/Support/Compiler.h"
3233 using namespace llvm;
3839 StrongPHIElimination() : MachineFunctionPass((intptr_t)&ID) {}
3940
4041 DenseMap
41 SmallVector, 2> > Waiting;
42 std::map> > Waiting;
43
44 std::map > Stacks;
45 std::set UsedByAnother;
4246
4347 bool runOnMachineFunction(MachineFunction &Fn);
4448
5559 preorder.clear();
5660 maxpreorder.clear();
5761
58 waiting.clear();
62 Waiting.clear();
5963 }
6064
6165 private:
8892 DenseMap preorder;
8993 DenseMap maxpreorder;
9094
91 DenseMap > waiting;
92
9395
9496 void computeDFS(MachineFunction& MF);
9597 void processBlock(MachineBasicBlock* MBB);
99101 std::set& PHIUnion,
100102 std::vector& DF,
101103 std::vector >& locals);
102
104 void ScheduleCopies(MachineBasicBlock* MBB);
103105 };
104106
105107 char StrongPHIElimination::ID = 0;
382384
383385 // add a copy from a_i to p in Waiting[From[a_i]]
384386 MachineBasicBlock* From = P->getOperand(i).getMachineBasicBlock();
385 Waiting[From].push_back(std::make_pair(SrcReg, DestReg));
387 Waiting[From].insert(std::make_pair(SrcReg, DestReg));
388 UsedByAnother.insert(SrcReg);
386389 } else {
387390 PHIUnion.insert(SrcReg);
388391 UnionedBlocks.insert(SrcInfo.DefInst->getParent());
430433 unsigned SrcReg = p.first;
431434 MachineBasicBlock* From = P->getOperand(i).getMBB();
432435
433 Waiting[From].push_back(std::make_pair(SrcReg,
434 P->getOperand(0).getReg()));
436 Waiting[From].insert(std::make_pair(SrcReg,
437 P->getOperand(0).getReg()));
438 UsedByAnother.insert(SrcReg);
439
435440 PHIUnion.erase(SrcReg);
436441 }
437442 }
480485 unsigned SrcReg = DFNode->getReg();
481486 MachineBasicBlock* From = Inst->getOperand(i).getMBB();
482487
483 Waiting[From].push_back(std::make_pair(SrcReg, DestReg));
488 Waiting[From].insert(std::make_pair(SrcReg, DestReg));
489 UsedByAnother.insert(SrcReg);
490
484491 PHIUnion.erase(SrcReg);
485492 }
486493 }
500507 }
501508 }
502509
510 /// ScheduleCopies - Insert copies into predecessor blocks, scheduling
511 /// them properly so as to avoid the 'lost copy' and the 'virtual swap'
512 /// problems.
513 ///
514 /// Based on "Practical Improvements to the Construction and Destruction
515 /// of Static Single Assignment Form" by Briggs, et al.
516 void StrongPHIElimination::ScheduleCopies(MachineBasicBlock* MBB) {
517 std::map& copy_set= Waiting[MBB];
518
519 std::map worklist;
520 std::map map;
521
522 // Setup worklist of initial copies
523 for (std::map::iterator I = copy_set.begin(),
524 E = copy_set.end(); I != E; ) {
525 map.insert(std::make_pair(I->first, I->first));
526 map.insert(std::make_pair(I->second, I->second));
527
528 if (!UsedByAnother.count(I->first)) {
529 worklist.insert(*I);
530
531 // Avoid iterator invalidation
532 unsigned first = I->first;
533 ++I;
534 copy_set.erase(first);
535 } else {
536 ++I;
537 }
538 }
539
540 LiveVariables& LV = getAnalysis();
541
542 // Iterate over the worklist, inserting copies
543 while (!worklist.empty() || !copy_set.empty()) {
544 while (!worklist.empty()) {
545 std::pair curr = *worklist.begin();
546 worklist.erase(curr.first);
547
548 if (isLiveOut(LV.getVarInfo(curr.second), MBB)) {
549 // Insert copy from curr.second to a temporary
550 // Push temporary on Stacks
551 }
552
553 // Insert copy from map[curr.first] to curr.second
554 map[curr.first] = curr.second;
555
556 // If curr.first is a destination in copy_set...
557 for (std::map::iterator I = copy_set.begin(),
558 E = copy_set.end(); I != E; )
559 if (curr.first == I->second) {
560 std::pair temp = *I;
561
562 // Avoid iterator invalidation
563 ++I;
564 copy_set.erase(temp.first);
565 worklist.insert(temp);
566
567 break;
568 } else {
569 ++I;
570 }
571 }
572
573 if (!copy_set.empty()) {
574 std::pair curr = *copy_set.begin();
575 copy_set.erase(curr.first);
576
577 // Insert a copy from dest to a new temporary t at the end of b
578 // map[curr.second] = t;
579
580 worklist.insert(curr);
581 }
582 }
583 }
584
503585 bool StrongPHIElimination::runOnMachineFunction(MachineFunction &Fn) {
586 // Compute DFS numbers of each block
504587 computeDFS(Fn);
505588
589 // Determine which phi node operands need copies
506590 for (MachineFunction::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I)
507591 if (!I->empty() &&
508592 I->begin()->getOpcode() == TargetInstrInfo::PHI)
509593 processBlock(I);
510594
511 // FIXME: Insert copies
595 // Insert copies
596 MachineDominatorTree& MDT = getAnalysis();
597 for (df_iterator DI = df_begin(MDT.getRootNode()),
598 DE = df_end(MDT.getRootNode()); DI != DE; ++DI) {
599 MachineBasicBlock* block = DI->getBlock();
600
601 // FIXME: Do rewriting with Stacks
602
603 ScheduleCopies(block);
604 }
605
512606 // FIXME: Perform renaming
513607
514608 return false;