Generalize the PassConfig API and remove addFinalizeRegAlloc().

The target hooks are getting out of hand. What does it mean to run
before or after regalloc anyway? Allowing either Pass* or AnalysisID
pass identification should make it much easier for targets to use the
substitutePass and insertPass APIs, and create less need for badly
named target hooks.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179140 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Andrew Trick
2013-04-10 01:06:56 +00:00
parent a9a5c537ad
commit 5ed028385c
2 changed files with 95 additions and 50 deletions

View File

@@ -35,6 +35,46 @@ namespace llvm {
class PassConfigImpl;
/// Discriminated union of Pass ID types.
///
/// The PassConfig API prefers dealing with IDs because they are safer and more
/// efficient. IDs decouple configuration from instantiation. This way, when a
/// pass is overriden, it isn't unnecessarily instantiated. It is also unsafe to
/// refer to a Pass pointer after adding it to a pass manager, which deletes
/// redundant pass instances.
///
/// However, it is convient to directly instantiate target passes with
/// non-default ctors. These often don't have a registered PassInfo. Rather than
/// force all target passes to implement the pass registry boilerplate, allow
/// the PassConfig API to handle either type.
///
/// AnalysisID is sadly char*, so PointerIntPair won't work.
class IdentifyingPassPtr {
void *P;
bool IsInstance;
public:
IdentifyingPassPtr(): P(0), IsInstance(false) {}
IdentifyingPassPtr(AnalysisID IDPtr): P((void*)IDPtr), IsInstance(false) {}
IdentifyingPassPtr(Pass *InstancePtr)
: P((void*)InstancePtr), IsInstance(true) {}
bool isValid() const { return P; }
bool isInstance() const { return IsInstance; }
AnalysisID getID() const {
assert(!IsInstance && "Not a Pass ID");
return (AnalysisID)P;
}
Pass *getInstance() const {
assert(IsInstance && "Not a Pass Instance");
return (Pass *)P;
}
};
template <> struct isPodLike<IdentifyingPassPtr> {
static const bool value = true;
};
/// Target-Independent Code Generator Pass Configuration Options.
///
/// This is an ImmutablePass solely for the purpose of exposing CodeGen options
@@ -117,20 +157,22 @@ public:
/// Allow the target to override a specific pass without overriding the pass
/// pipeline. When passes are added to the standard pipeline at the
/// point where StandardID is expected, add TargetID in its place.
void substitutePass(AnalysisID StandardID, AnalysisID TargetID);
void substitutePass(AnalysisID StandardID, IdentifyingPassPtr TargetID);
/// Insert InsertedPassID pass after TargetPassID pass.
void insertPass(AnalysisID TargetPassID, AnalysisID InsertedPassID);
void insertPass(AnalysisID TargetPassID, IdentifyingPassPtr InsertedPassID);
/// Allow the target to enable a specific standard pass by default.
void enablePass(AnalysisID PassID) { substitutePass(PassID, PassID); }
/// Allow the target to disable a specific standard pass by default.
void disablePass(AnalysisID PassID) { substitutePass(PassID, 0); }
void disablePass(AnalysisID PassID) {
substitutePass(PassID, IdentifyingPassPtr());
}
/// Return the pass substituted for StandardID by the target.
/// If no substitution exists, return StandardID.
AnalysisID getPassSubstitution(AnalysisID StandardID) const;
IdentifyingPassPtr getPassSubstitution(AnalysisID StandardID) const;
/// Return true if the optimized regalloc pipeline is enabled.
bool getOptimizeRegAlloc() const;
@@ -222,17 +264,6 @@ protected:
return false;
}
/// addFinalizeRegAlloc - This method may be implemented by targets that want
/// to run passes within the regalloc pipeline, immediately after the register
/// allocation pass itself. These passes run as soon as virtual regisiters
/// have been rewritten to physical registers but before and other postRA
/// optimization happens. Targets that have marked instructions for bundling
/// must have finalized those bundles by the time these passes have run,
/// because subsequent passes are not guaranteed to be bundle-aware.
virtual bool addFinalizeRegAlloc() {
return false;
}
/// addPostRegAlloc - This method may be implemented by targets that want to
/// run passes after register allocation pass pipeline but before
/// prolog-epilog insertion. This should return true if -print-machineinstrs