From 668ac2fdae69ed358ecf690d6a07428e5a9ee2f7 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 16 Nov 2010 21:02:37 +0000 Subject: [PATCH] Split pseudo-instruction expansion into a separate pass, to make it easier to debug, and to avoid complications when the CFG changes in the middle of the instruction selection process. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@119382 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/Passes.h | 4 ++ include/llvm/InitializePasses.h | 1 + lib/CodeGen/ExpandPseudos.cpp | 84 +++++++++++++++++++++++ lib/CodeGen/LLVMTargetMachine.cpp | 3 + lib/CodeGen/SelectionDAG/InstrEmitter.cpp | 13 ---- 5 files changed, 92 insertions(+), 13 deletions(-) create mode 100644 lib/CodeGen/ExpandPseudos.cpp diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h index bbedabd4077..7345f15dd1c 100644 --- a/include/llvm/CodeGen/Passes.h +++ b/include/llvm/CodeGen/Passes.h @@ -213,6 +213,10 @@ namespace llvm { /// addressing. FunctionPass *createLocalStackSlotAllocationPass(); + /// createExpandPseudosPass - This pass expands pseudo-instructions. + /// + FunctionPass *createExpandPseudosPass(); + } // End llvm namespace #endif diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h index 50443e2f3fe..23f918797db 100644 --- a/include/llvm/InitializePasses.h +++ b/include/llvm/InitializePasses.h @@ -92,6 +92,7 @@ void initializeDomViewerPass(PassRegistry&); void initializeDominanceFrontierPass(PassRegistry&); void initializeDominatorTreePass(PassRegistry&); void initializeEdgeProfilerPass(PassRegistry&); +void initializeExpandPseudosPass(PassRegistry&); void initializeFindUsedTypesPass(PassRegistry&); void initializeFunctionAttrsPass(PassRegistry&); void initializeGCModuleInfoPass(PassRegistry&); diff --git a/lib/CodeGen/ExpandPseudos.cpp b/lib/CodeGen/ExpandPseudos.cpp new file mode 100644 index 00000000000..4f9e8ad2ae0 --- /dev/null +++ b/lib/CodeGen/ExpandPseudos.cpp @@ -0,0 +1,84 @@ +//===-- llvm/CodeGen/ExpandPseudos.cpp --------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Expand Psuedo-instructions produced by ISel. These is usually to allow +// the expansion to contain control flow, such as a conditional move +// implemented with a conditional branch and a phi, or an atomic operation +// implemented with a loop. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "expand-pseudos" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/Passes.h" +#include "llvm/Target/TargetLowering.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Support/Debug.h" +using namespace llvm; + +namespace { + class ExpandPseudos : public MachineFunctionPass { + public: + static char ID; // Pass identification, replacement for typeid + ExpandPseudos() : MachineFunctionPass(ID) {} + + private: + virtual bool runOnMachineFunction(MachineFunction &MF); + + const char *getPassName() const { + return "Expand CodeGen Pseudo-instructions"; + } + + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + MachineFunctionPass::getAnalysisUsage(AU); + } + }; +} // end anonymous namespace + +char ExpandPseudos::ID = 0; +INITIALIZE_PASS_BEGIN(ExpandPseudos, "expand-pseudos", + "Expand CodeGen Psueod-instructions", false, false) +INITIALIZE_PASS_END(ExpandPseudos, "expand-pseudos", + "Expand CodeGen Psueod-instructions", false, false) + +FunctionPass *llvm::createExpandPseudosPass() { + return new ExpandPseudos(); +} + +bool ExpandPseudos::runOnMachineFunction(MachineFunction &MF) { + bool Changed = false; + const TargetLowering *TLI = MF.getTarget().getTargetLowering(); + + // Iterate through each instruction in the function, looking for pseudos. + for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) { + MachineBasicBlock *MBB = I; + for (MachineBasicBlock::iterator MBBI = MBB->begin(), MBBE = MBB->end(); + MBBI != MBBE; ) { + MachineInstr *MI = MBBI++; + + // If MI is a pseudo, expand it. + const TargetInstrDesc &TID = MI->getDesc(); + if (TID.usesCustomInsertionHook()) { + Changed = true; + MachineBasicBlock *NewMBB = + TLI->EmitInstrWithCustomInserter(MI, MBB); + // The expansion may involve new basic blocks. + if (NewMBB != MBB) { + MBB = NewMBB; + I = NewMBB; + MBBI = NewMBB->begin(); + MBBE = NewMBB->end(); + } + } + } + } + + return Changed; +} diff --git a/lib/CodeGen/LLVMTargetMachine.cpp b/lib/CodeGen/LLVMTargetMachine.cpp index 3ba1b89a802..d19b319884e 100644 --- a/lib/CodeGen/LLVMTargetMachine.cpp +++ b/lib/CodeGen/LLVMTargetMachine.cpp @@ -345,6 +345,9 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM, // Print the instruction selected machine code... printAndVerify(PM, "After Instruction Selection"); + // Expand pseudo-instructions emitted by isel. + PM.add(createExpandPseudosPass()); + // Optimize PHIs before DCE: removing dead PHI cycles may make more // instructions dead. if (OptLevel != CodeGenOpt::None) diff --git a/lib/CodeGen/SelectionDAG/InstrEmitter.cpp b/lib/CodeGen/SelectionDAG/InstrEmitter.cpp index 61c2a90e7ed..1445abed2ee 100644 --- a/lib/CodeGen/SelectionDAG/InstrEmitter.cpp +++ b/lib/CodeGen/SelectionDAG/InstrEmitter.cpp @@ -721,19 +721,6 @@ EmitMachineNode(SDNode *Node, bool IsClone, bool IsCloned, // hook knows where in the block to insert the replacement code. MBB->insert(InsertPos, MI); - if (II.usesCustomInsertionHook()) { - // Insert this instruction into the basic block using a target - // specific inserter which may returns a new basic block. - bool AtEnd = InsertPos == MBB->end(); - MachineBasicBlock *NewMBB = TLI->EmitInstrWithCustomInserter(MI, MBB); - if (NewMBB != MBB) { - if (AtEnd) - InsertPos = NewMBB->end(); - MBB = NewMBB; - } - return; - } - // Additional results must be an physical register def. if (HasPhysRegOuts) { for (unsigned i = II.getNumDefs(); i < NumResults; ++i) {