From: Owen Anderson Date: Wed, 31 Oct 2007 03:37:57 +0000 (+0000) Subject: Add the skeleton of a better PHI elimination pass. X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=0bda0e8895285c3a03c8859e11f2fff69861fd9d;p=oota-llvm.git Add the skeleton of a better PHI elimination pass. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@43542 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h index ed96b40a109..5e93525ab47 100644 --- a/include/llvm/CodeGen/Passes.h +++ b/include/llvm/CodeGen/Passes.h @@ -44,6 +44,14 @@ namespace llvm { /// these register allocator like this: AU.addRequiredID(PHIEliminationID); /// extern const PassInfo *PHIEliminationID; + + /// StrongPHIElimination pass - This pass eliminates machine instruction PHI + /// nodes by inserting copy instructions. This destroys SSA information, but + /// is the desired input for some register allocators. This pass is + /// "required" by these register allocator like this: + /// AU.addRequiredID(PHIEliminationID); + /// This pass is still in development + extern const PassInfo *StrongPHIEliminationID; /// SimpleRegisterCoalescing pass. Aggressively coalesces every register /// copy it can. diff --git a/lib/CodeGen/StrongPHIElimination.cpp b/lib/CodeGen/StrongPHIElimination.cpp new file mode 100644 index 00000000000..500baae20ec --- /dev/null +++ b/lib/CodeGen/StrongPHIElimination.cpp @@ -0,0 +1,112 @@ +//===- StrongPhiElimination.cpp - Eliminate PHI nodes by inserting copies -===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by Owen Anderson and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This pass eliminates machine instruction PHI nodes by inserting copy +// instructions, using an intelligent copy-folding technique based on +// dominator information. This is technique is derived from: +// +// Budimlic, et al. Fast copy coalescing and live-range identification. +// In Proceedings of the ACM SIGPLAN 2002 Conference on Programming Language +// Design and Implementation (Berlin, Germany, June 17 - 19, 2002). +// PLDI '02. ACM, New York, NY, 25-32. +// DOI= http://doi.acm.org/10.1145/512529.512534 +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "strongphielim" +#include "llvm/CodeGen/Passes.h" +#include "llvm/CodeGen/MachineDominators.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/Target/TargetInstrInfo.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/Support/Compiler.h" +using namespace llvm; + + +namespace { + struct VISIBILITY_HIDDEN StrongPHIElimination : public MachineFunctionPass { + static char ID; // Pass identification, replacement for typeid + StrongPHIElimination() : MachineFunctionPass((intptr_t)&ID) {} + + bool runOnMachineFunction(MachineFunction &Fn) { + computeDFS(Fn); + + + return false; + } + + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired(); + MachineFunctionPass::getAnalysisUsage(AU); + } + + virtual void releaseMemory() { + preorder.clear(); + maxpreorder.clear(); + } + + private: + DenseMap preorder; + DenseMap maxpreorder; + + void computeDFS(MachineFunction& MF); + }; + + char StrongPHIElimination::ID = 0; + RegisterPass X("strong-phi-node-elimination", + "Eliminate PHI nodes for register allocation, intelligently"); +} + +const PassInfo *llvm::StrongPHIEliminationID = X.getPassInfo(); + +/// computeDFS - Computes the DFS-in and DFS-out numbers of the dominator tree +/// of the given MachineFunction. These numbers are then used in other parts +/// of the PHI elimination process. +void StrongPHIElimination::computeDFS(MachineFunction& MF) { + SmallPtrSet frontier; + SmallPtrSet visited; + + unsigned time = 0; + + MachineDominatorTree& DT = getAnalysis(); + + MachineDomTreeNode* node = DT.getRootNode(); + + std::vector worklist; + worklist.push_back(node); + + while (!worklist.empty()) { + MachineDomTreeNode* currNode = worklist.back(); + + if (!frontier.count(currNode)) { + frontier.insert(currNode); + ++time; + preorder.insert(std::make_pair(currNode->getBlock(), time)); + } + + bool inserted = false; + for (MachineDomTreeNode::iterator I = node->begin(), E = node->end(); + I != E; ++I) + if (!frontier.count(*I) && !visited.count(*I)) { + worklist.push_back(*I); + inserted = true; + break; + } + + if (!inserted) { + frontier.erase(currNode); + visited.insert(currNode); + maxpreorder.insert(std::make_pair(currNode->getBlock(), time)); + + worklist.pop_back(); + } + } +} \ No newline at end of file