Manage MachineFunctions with an analysis Pass instead of the Annotable

mechanism. To support this, make MachineFunctionPass a little more
complete.

llvm-svn: 77654
This commit is contained in:
Dan Gohman 2009-07-31 01:52:50 +00:00
parent dfbd0c4b0d
commit bcb44baa57
18 changed files with 187 additions and 136 deletions

View File

@ -34,6 +34,7 @@ public:
void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
AU.addRequired<MachineDominatorTree>();
MachineFunctionPass::getAnalysisUsage(AU);
}
bool runOnMachineFunction(MachineFunction &mf);

View File

@ -67,7 +67,7 @@ struct MachineFunctionInfo {
};
class MachineFunction : private Annotation {
const Function *Fn;
Function *Fn;
const TargetMachine &Target;
// RegInfo - Information about each register in use in the function.
@ -115,12 +115,12 @@ class MachineFunction : private Annotation {
unsigned Alignment;
public:
MachineFunction(const Function *Fn, const TargetMachine &TM);
MachineFunction(Function *Fn, const TargetMachine &TM);
~MachineFunction();
/// getFunction - Return the LLVM function that this machine code represents
///
const Function *getFunction() const { return Fn; }
Function *getFunction() const { return Fn; }
/// getTarget - Return the target machine this machine code is compiled with
///
@ -229,21 +229,6 @@ public:
///
void dump() const;
/// construct - Allocate and initialize a MachineFunction for a given Function
/// and Target
///
static MachineFunction& construct(const Function *F, const TargetMachine &TM);
/// destruct - Destroy the MachineFunction corresponding to a given Function
///
static void destruct(const Function *F);
/// get - Return a handle to a MachineFunction corresponding to the given
/// Function. This should not be called before "construct()" for a given
/// Function.
///
static MachineFunction& get(const Function *F);
// Provide accessors for the MachineBasicBlock list...
typedef BasicBlockListType::iterator iterator;
typedef BasicBlockListType::const_iterator const_iterator;

View File

@ -0,0 +1,49 @@
//===-- MachineFunctionAnalysis.h - Owner of MachineFunctions ----*-C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file declares the MachineFunctionAnalysis class.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CODEGEN_MACHINE_FUNCTION_ANALYSIS_H
#define LLVM_CODEGEN_MACHINE_FUNCTION_ANALYSIS_H
#include "llvm/Pass.h"
#include "llvm/Target/TargetMachine.h"
namespace llvm {
class MachineFunction;
/// MachineFunctionAnalysis - This class is a Pass that manages a
/// MachineFunction object.
struct MachineFunctionAnalysis : public FunctionPass {
private:
const TargetMachine &TM;
CodeGenOpt::Level OptLevel;
MachineFunction *MF;
public:
static char ID;
explicit MachineFunctionAnalysis(TargetMachine &tm,
CodeGenOpt::Level OL = CodeGenOpt::Default);
MachineFunction &getMF() const { return *MF; }
CodeGenOpt::Level getOptLevel() const { return OptLevel; }
private:
virtual bool runOnFunction(Function &F);
virtual void releaseMemory();
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
};
} // End llvm namespace
#endif

View File

@ -24,19 +24,25 @@
namespace llvm {
// FIXME: This pass should declare that the pass does not invalidate any LLVM
// passes.
struct MachineFunctionPass : public FunctionPass {
/// MachineFunctionPass - This class adapts the FunctionPass interface to
/// allow convenient creation of passes that operate on the MachineFunction
/// representation. Instead of overriding runOnFunction, subclasses
/// override runOnMachineFunction.
class MachineFunctionPass : public FunctionPass {
protected:
explicit MachineFunctionPass(intptr_t ID) : FunctionPass(ID) {}
explicit MachineFunctionPass(void *ID) : FunctionPass(ID) {}
protected:
/// runOnMachineFunction - This method must be overloaded to perform the
/// desired machine code transformation or analysis.
///
virtual bool runOnMachineFunction(MachineFunction &MF) = 0;
public:
/// getAnalysisUsage - Subclasses that override getAnalysisUsage
/// must call this.
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
private:
bool runOnFunction(Function &F);
};

View File

@ -146,11 +146,6 @@ namespace llvm {
/// by seeing if the labels map to the same reduced label.
FunctionPass *createDebugLabelFoldingPass();
/// MachineCodeDeletion Pass - This pass deletes all of the machine code for
/// the current function, which should happen after the function has been
/// emitted to a .s file or to memory.
FunctionPass *createMachineCodeDeleter();
/// getRegisterAllocator - This creates an instance of the register allocator
/// for the Sparc.
FunctionPass *getRegisterAllocator(TargetMachine &T);

View File

@ -19,6 +19,7 @@
#include "llvm/Pass.h"
#include "llvm/Constant.h"
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
namespace llvm {
class FastISel;
@ -39,7 +40,7 @@ namespace llvm {
/// SelectionDAGISel - This is the common base class used for SelectionDAG-based
/// pattern-matching instruction selectors.
class SelectionDAGISel : public FunctionPass {
class SelectionDAGISel : public MachineFunctionPass {
public:
const TargetMachine &TM;
TargetLowering &TLI;
@ -62,7 +63,7 @@ public:
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
virtual bool runOnFunction(Function &Fn);
virtual bool runOnMachineFunction(MachineFunction &MF);
unsigned MakeReg(MVT VT);

View File

@ -21,7 +21,6 @@
#include "llvm/GlobalValue.h"
#include "llvm/BasicBlock.h"
#include "llvm/Argument.h"
#include "llvm/Support/Annotation.h"
#include "llvm/Attributes.h"
namespace llvm {
@ -66,7 +65,7 @@ private:
mutable ilist_node<Argument> Sentinel;
};
class Function : public GlobalValue, public Annotable,
class Function : public GlobalValue,
public ilist_node<Function> {
public:
typedef iplist<Argument> ArgumentListType;

View File

@ -18,6 +18,7 @@
#include "llvm/Analysis/LoopPass.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/GCStrategy.h"
#include "llvm/CodeGen/MachineFunctionAnalysis.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetAsmInfo.h"
#include "llvm/Target/TargetRegistry.h"
@ -118,9 +119,6 @@ bool LLVMTargetMachine::addPassesToEmitFileFinish(PassManagerBase &PM,
PM.add(createGCInfoDeleter());
// Delete machine code for this function
PM.add(createMachineCodeDeleter());
return false; // success!
}
@ -137,9 +135,6 @@ bool LLVMTargetMachine::addPassesToEmitFileFinish(PassManagerBase &PM,
PM.add(createGCInfoDeleter());
// Delete machine code for this function
PM.add(createMachineCodeDeleter());
return false; // success!
}
@ -156,9 +151,6 @@ bool LLVMTargetMachine::addPassesToEmitFileFinish(PassManagerBase &PM,
PM.add(createGCInfoDeleter());
// Delete machine code for this function
PM.add(createMachineCodeDeleter());
return false; // success!
}
@ -184,9 +176,6 @@ bool LLVMTargetMachine::addPassesToEmitMachineCode(PassManagerBase &PM,
PM.add(createGCInfoDeleter());
// Delete machine code for this function
PM.add(createMachineCodeDeleter());
return false; // success!
}
@ -212,9 +201,6 @@ bool LLVMTargetMachine::addPassesToEmitMachineCode(PassManagerBase &PM,
PM.add(createGCInfoDeleter());
// Delete machine code for this function
PM.add(createMachineCodeDeleter());
return false; // success!
}
@ -265,6 +251,9 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM,
// Standard Lower-Level Passes.
// Set up a MachineFunction for the rest of CodeGen to work on.
PM.add(new MachineFunctionAnalysis(*this, OptLevel));
// Enable FastISel with -fast, but allow that to be overridden.
if (EnableFastISelOption == cl::BOU_TRUE ||
(OptLevel == CodeGenOpt::None && EnableFastISelOption != cl::BOU_FALSE))

View File

@ -48,6 +48,7 @@ static RegisterPass<LiveVariables> X("livevars", "Live Variable Analysis");
void LiveVariables::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequiredID(UnreachableMachineBlockElimID);
AU.setPreservesAll();
MachineFunctionPass::getAnalysisUsage(AU);
}
void LiveVariables::VarInfo::dump() const {

View File

@ -36,15 +36,6 @@
#include <sstream>
using namespace llvm;
bool MachineFunctionPass::runOnFunction(Function &F) {
// Do not codegen any 'available_externally' functions at all, they have
// definitions outside the translation unit.
if (F.hasAvailableExternallyLinkage())
return false;
return runOnMachineFunction(MachineFunction::get(&F));
}
namespace {
struct VISIBILITY_HIDDEN Printer : public MachineFunctionPass {
static char ID;
@ -59,6 +50,7 @@ namespace {
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
MachineFunctionPass::getAnalysisUsage(AU);
}
bool runOnMachineFunction(MachineFunction &MF) {
@ -78,31 +70,6 @@ FunctionPass *llvm::createMachineFunctionPrinterPass(std::ostream *OS,
return new Printer(OS, Banner);
}
namespace {
struct VISIBILITY_HIDDEN Deleter : public MachineFunctionPass {
static char ID;
Deleter() : MachineFunctionPass(&ID) {}
const char *getPassName() const { return "Machine Code Deleter"; }
bool runOnMachineFunction(MachineFunction &MF) {
// Delete the annotation from the function now.
MachineFunction::destruct(MF.getFunction());
return true;
}
};
char Deleter::ID = 0;
}
/// MachineCodeDeletion Pass - This pass deletes all of the machine code for
/// the current function, which should happen after the function has been
/// emitted to a .s file or to memory.
FunctionPass *llvm::createMachineCodeDeleter() {
return new Deleter();
}
//===---------------------------------------------------------------------===//
// MachineFunction implementation
//===---------------------------------------------------------------------===//
@ -111,7 +78,7 @@ void ilist_traits<MachineBasicBlock>::deleteNode(MachineBasicBlock *MBB) {
MBB->getParent()->DeleteMachineBasicBlock(MBB);
}
MachineFunction::MachineFunction(const Function *F,
MachineFunction::MachineFunction(Function *F,
const TargetMachine &TM)
: Annotation(AnnotationManager::getID("CodeGen::MachineCodeForFunction")),
Fn(F), Target(TM) {
@ -356,42 +323,6 @@ void MachineFunction::viewCFGOnly() const
#endif // NDEBUG
}
// The next two methods are used to construct and to retrieve
// the MachineCodeForFunction object for the given function.
// construct() -- Allocates and initializes for a given function and target
// get() -- Returns a handle to the object.
// This should not be called before "construct()"
// for a given Function.
//
MachineFunction&
MachineFunction::construct(const Function *Fn, const TargetMachine &Tar)
{
AnnotationID MF_AID =
AnnotationManager::getID("CodeGen::MachineCodeForFunction");
assert(Fn->getAnnotation(MF_AID) == 0 &&
"Object already exists for this function!");
MachineFunction* mcInfo = new MachineFunction(Fn, Tar);
Fn->addAnnotation(mcInfo);
return *mcInfo;
}
void MachineFunction::destruct(const Function *Fn) {
AnnotationID MF_AID =
AnnotationManager::getID("CodeGen::MachineCodeForFunction");
bool Deleted = Fn->deleteAnnotation(MF_AID);
assert(Deleted && "Machine code did not exist for function!");
Deleted = Deleted; // silence warning when no assertions.
}
MachineFunction& MachineFunction::get(const Function *F)
{
AnnotationID MF_AID =
AnnotationManager::getID("CodeGen::MachineCodeForFunction");
MachineFunction *mc = (MachineFunction*)F->getAnnotation(MF_AID);
assert(mc && "Call construct() method first to allocate the object");
return *mc;
}
/// addLiveIn - Add the specified physical register as a live-in value and
/// create a corresponding virtual register for it.
unsigned MachineFunction::addLiveIn(unsigned PReg,

View File

@ -0,0 +1,45 @@
//===-- MachineFunctionAnalysis.cpp ---------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the definitions of the MachineFunctionAnalysis members.
//
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/MachineFunctionAnalysis.h"
#include "llvm/CodeGen/MachineFunction.h"
using namespace llvm;
// Register this pass with PassInfo directly to avoid having to define
// a default constructor.
static PassInfo
X("Machine Function Analysis", "machine-function-analysis",
intptr_t(&MachineFunctionAnalysis::ID), 0,
/*CFGOnly=*/false, /*is_analysis=*/true);
char MachineFunctionAnalysis::ID = 0;
MachineFunctionAnalysis::MachineFunctionAnalysis(TargetMachine &tm,
CodeGenOpt::Level OL) :
FunctionPass(&ID), TM(tm), OptLevel(OL), MF(0) {
}
bool MachineFunctionAnalysis::runOnFunction(Function &F) {
assert(!MF && "MachineFunctionAnalysis already initialized!");
MF = new MachineFunction(&F, TM);
return false;
}
void MachineFunctionAnalysis::releaseMemory() {
delete MF;
MF = 0;
}
void MachineFunctionAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
}

View File

@ -0,0 +1,50 @@
//===-- MachineFunctionPass.cpp -------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the definitions of the MachineFunctionPass members.
//
//===----------------------------------------------------------------------===//
#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/ScalarEvolution.h"
#include "llvm/Analysis/IVUsers.h"
#include "llvm/Analysis/LiveValues.h"
#include "llvm/Analysis/LoopDependenceAnalysis.h"
#include "llvm/Analysis/MemoryDependenceAnalysis.h"
#include "llvm/CodeGen/MachineFunctionAnalysis.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
using namespace llvm;
bool MachineFunctionPass::runOnFunction(Function &F) {
// Do not codegen any 'available_externally' functions at all, they have
// definitions outside the translation unit.
if (F.hasAvailableExternallyLinkage())
return false;
MachineFunction &MF = getAnalysis<MachineFunctionAnalysis>().getMF();
return runOnMachineFunction(MF);
}
void MachineFunctionPass::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<MachineFunctionAnalysis>();
// MachineFunctionPass preserves all LLVM IR passes, but there's no
// high-level way to express this. Instead, just list a bunch of
// passes explicitly.
AU.addPreserved<AliasAnalysis>();
AU.addPreserved<ScalarEvolution>();
AU.addPreserved<IVUsers>();
AU.addPreserved<LoopDependenceAnalysis>();
AU.addPreserved<MemoryDependenceAnalysis>();
AU.addPreserved<LiveValues>();
AU.addPreserved<MachineFunctionAnalysis>();
AU.setPreservesCFG();
FunctionPass::getAnalysisUsage(AU);
}

View File

@ -41,4 +41,5 @@ bool MachineLoopInfo::runOnMachineFunction(MachineFunction &) {
void MachineLoopInfo::getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
AU.addRequired<MachineDominatorTree>();
MachineFunctionPass::getAnalysisUsage(AU);
}

View File

@ -55,6 +55,7 @@ namespace {
void getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
MachineFunctionPass::getAnalysisUsage(AU);
}
bool runOnMachineFunction(MachineFunction &MF);

View File

@ -111,7 +111,6 @@ bool PEI::runOnMachineFunction(MachineFunction &Fn) {
#if 0
void PEI::getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesCFG();
if (ShrinkWrapping || ShrinkWrapFunc != "") {
AU.addRequired<MachineLoopInfo>();
AU.addRequired<MachineDominatorTree>();

View File

@ -29,6 +29,7 @@
#include "llvm/CodeGen/GCStrategy.h"
#include "llvm/CodeGen/GCMetadata.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionAnalysis.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
@ -267,7 +268,7 @@ static void EmitLiveInCopies(MachineBasicBlock *EntryMBB,
//===----------------------------------------------------------------------===//
SelectionDAGISel::SelectionDAGISel(TargetMachine &tm, CodeGenOpt::Level OL) :
FunctionPass(&ID), TM(tm), TLI(*tm.getTargetLowering()),
MachineFunctionPass(&ID), TM(tm), TLI(*tm.getTargetLowering()),
FuncInfo(new FunctionLoweringInfo(TLI)),
CurDAG(new SelectionDAG(TLI, *FuncInfo)),
SDL(new SelectionDAGLowering(*CurDAG, TLI, *FuncInfo, OL)),
@ -291,9 +292,12 @@ void SelectionDAGISel::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<GCModuleInfo>();
AU.addRequired<DwarfWriter>();
AU.setPreservesAll();
MachineFunctionPass::getAnalysisUsage(AU);
}
bool SelectionDAGISel::runOnFunction(Function &Fn) {
bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
Function &Fn = *mf.getFunction();
// Do some sanity-checking on the command-line options.
assert((!EnableFastISelVerbose || EnableFastISel) &&
"-fast-isel-verbose requires -fast-isel");
@ -305,12 +309,11 @@ bool SelectionDAGISel::runOnFunction(Function &Fn) {
if (Fn.hasAvailableExternallyLinkage())
return false;
// Get alias analysis for load/store combining.
AA = &getAnalysis<AliasAnalysis>();
TargetMachine &TM = TLI.getTargetMachine();
MF = &MachineFunction::construct(&Fn, TM);
MF = &mf;
const TargetInstrInfo &TII = *TM.getInstrInfo();
const TargetRegisterInfo &TRI = *TM.getRegisterInfo();

View File

@ -253,10 +253,10 @@ namespace {
SPUtli(*tm.getTargetLowering())
{ }
virtual bool runOnFunction(Function &Fn) {
virtual bool runOnMachineFunction(MachineFunction &MF) {
// Make sure we re-emit a set of the global base reg if necessary
GlobalBaseReg = 0;
SelectionDAGISel::runOnFunction(Fn);
SelectionDAGISel::runOnMachineFunction(MF);
return true;
}

View File

@ -20,6 +20,7 @@
#include "PPCHazardRecognizers.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionAnalysis.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/SelectionDAG.h"
#include "llvm/CodeGen/SelectionDAGISel.h"
@ -51,17 +52,12 @@ namespace {
PPCLowering(*TM.getTargetLowering()),
PPCSubTarget(*TM.getSubtargetImpl()) {}
virtual bool runOnFunction(Function &Fn) {
// Do not codegen any 'available_externally' functions at all, they have
// definitions outside the translation unit.
if (Fn.hasAvailableExternallyLinkage())
return false;
virtual bool runOnMachineFunction(MachineFunction &MF) {
// Make sure we re-emit a set of the global base reg if necessary
GlobalBaseReg = 0;
SelectionDAGISel::runOnFunction(Fn);
SelectionDAGISel::runOnMachineFunction(MF);
InsertVRSaveCode(Fn);
InsertVRSaveCode(MF);
return true;
}
@ -181,7 +177,7 @@ namespace {
/// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
virtual void InstructionSelect();
void InsertVRSaveCode(Function &Fn);
void InsertVRSaveCode(MachineFunction &MF);
virtual const char *getPassName() const {
return "PowerPC DAG->DAG Pattern Instruction Selection";
@ -218,13 +214,12 @@ void PPCDAGToDAGISel::InstructionSelect() {
/// InsertVRSaveCode - Once the entire function has been instruction selected,
/// all virtual registers are created and all machine instructions are built,
/// check to see if we need to save/restore VRSAVE. If so, do it.
void PPCDAGToDAGISel::InsertVRSaveCode(Function &F) {
void PPCDAGToDAGISel::InsertVRSaveCode(MachineFunction &Fn) {
// Check to see if this function uses vector registers, which means we have to
// save and restore the VRSAVE register and update it with the regs we use.
//
// In this case, there will be virtual registers of vector type type created
// by the scheduler. Detect them now.
MachineFunction &Fn = MachineFunction::get(&F);
bool HasVectorVReg = false;
for (unsigned i = TargetRegisterInfo::FirstVirtualRegister,
e = RegInfo->getLastVirtReg()+1; i != e; ++i)