[PATCH] Add getters for Pass IDs used by Polly plug-in.

Matthew Curtis mcurtis at codeaurora.org
Wed Feb 6 06:15:38 PST 2013


Hello all,

This patch helps resolve a couple of issues we encountered while
porting the Polly plug-in to Windows.

The Polly plugin depends on some LLVM Passes which it identifies via
Pass IDs. Pass IDs are implemented as the address of a static member
variable (ID) of the Pass. On Windows however, there seems to be a bug
in the Visual Studio compiler or linker that results in multiple
dll-local copies of this data when referenced directly. The result is
that Polly is unable to locate Passes that are part of the executable
it is being loaded into.

As a work around, this patch adds getters (GetClassPassID) for the
Pass IDs used by Polly. The symbols for the globals are not
exported. The getters are exported and Polly uses them instead.

Removing use of global data by the Polly plug-in also makes it
possible to delay load LLVM symbols from the containing executable
which in turn removes the restriction that the executable have a
specific name (determined at link-time).

We also considered a couple alternatives to this minimal patch:

1) Update *all* Passes to provide GetClassPassID in lieu of ID.

    This leaves the code in the cleanest state and would be a good
    choice if starting from scratch. However I started implementing it
    and it turns out to have a very large ripple effect. Not only does
    it require changing a large number of files in LLVM, but it breaks
    source compatibility for passes that are not part of the LLVM
    source.

    That being said, I'd be willing to do the work if everyone thinks
    that's the right thing to do and we're willing break source
    compatibility.

    Perhaps we could ease the pain by deprecating ID for some time
    before removing it.

2) Add GetClassPassID to Passes accessible by plug-ins (i.e. those
    under include/llvm), but leave ID as it is.

    As with the proposed patch, this may cause confusion because there
    are multiple ways of getting a Pass's ID. But at least it's not
    specific to the Polly plug-in and other plug-ins on Windows may
    benefit.

Thanks,
Matthew Curtis

BTW, there's a brief related discussion on llvm-dev here:
http://lists.cs.uiuc.edu/pipermail/llvmdev/2013-January/058838.html
http://lists.cs.uiuc.edu/pipermail/llvmdev/2013-February/thread.html#58982

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation

-------------- next part --------------
>From ad5df3d55405f1616ec8ffaa1b9de4b0fa2c2aca Mon Sep 17 00:00:00 2001
From: Matthew Curtis <mcurtis at codeaurora.org>
Date: Tue, 5 Feb 2013 18:33:16 -0600
Subject: [PATCH] Add getters for Pass IDs used by Polly plug-in.

The Polly plugin depends on some LLVM Passes which it identifies via
Pass IDs. Pass IDs are implemented as the address of a static member
variable of the Pass. On Windows however, there seems to be a bug in
the Visual Studio compiler or linker that results in multiple
dll-local copies of this data when referenced directly. The result is
that Polly is unable to locate Passes that are part of the executable
it is being loaded into.

As a work around, this patch adds getters (GetClassPassID) for the
Pass IDs used by Polly. The symbols for the globals are not
exported. The getters are exported and Polly uses them instead.

Removing use of global data by the Polly plug-in also makes it
possible to delay load LLVM symbols from the containing executable
which in turn removes the restriction that the executable have a
specific name.
---
 include/llvm/Analysis/AliasAnalysis.h     |    1 +
 include/llvm/Analysis/DominanceFrontier.h |    1 +
 include/llvm/Analysis/Dominators.h        |    2 ++
 include/llvm/Analysis/IVUsers.h           |    2 ++
 include/llvm/Analysis/LoopInfo.h          |    1 +
 include/llvm/Analysis/PostDominators.h    |    1 +
 include/llvm/Analysis/RegionInfo.h        |    1 +
 include/llvm/Analysis/ScalarEvolution.h   |    1 +
 include/llvm/IR/DataLayout.h              |    1 +
 include/llvm/Transforms/Scalar.h          |    2 ++
 lib/Analysis/AliasAnalysis.cpp            |    3 +++
 lib/Analysis/DominanceFrontier.cpp        |    3 +++
 lib/Analysis/IVUsers.cpp                  |    3 +++
 lib/Analysis/LoopInfo.cpp                 |    4 ++++
 lib/Analysis/PostDominators.cpp           |    3 +++
 lib/Analysis/RegionInfo.cpp               |    3 +++
 lib/Analysis/ScalarEvolution.cpp          |    4 ++++
 lib/IR/DataLayout.cpp                     |    3 +++
 lib/IR/Dominators.cpp                     |    4 ++++
 lib/Transforms/Utils/LCSSA.cpp            |    1 +
 lib/Transforms/Utils/LoopSimplify.cpp     |    1 +
 21 files changed, 45 insertions(+), 0 deletions(-)

diff --git a/include/llvm/Analysis/AliasAnalysis.h b/include/llvm/Analysis/AliasAnalysis.h
index d703f21..d251a46 100644
--- a/include/llvm/Analysis/AliasAnalysis.h
+++ b/include/llvm/Analysis/AliasAnalysis.h
@@ -75,6 +75,7 @@ protected:
 
 public:
   static char ID; // Class identification, replacement for typeinfo
+  static const void *GetClassPassID();
   AliasAnalysis() : TD(0), TLI(0), AA(0) {}
   virtual ~AliasAnalysis();  // We want to be subclassed
 
diff --git a/include/llvm/Analysis/DominanceFrontier.h b/include/llvm/Analysis/DominanceFrontier.h
index a2e0675..b22ba43 100644
--- a/include/llvm/Analysis/DominanceFrontier.h
+++ b/include/llvm/Analysis/DominanceFrontier.h
@@ -157,6 +157,7 @@ class DominanceFrontier : public DominanceFrontierBase {
   virtual void anchor();
 public:
   static char ID; // Pass ID, replacement for typeid
+  static AnalysisID GetClassPassID();
   DominanceFrontier() :
     DominanceFrontierBase(ID, false) {
       initializeDominanceFrontierPass(*PassRegistry::getPassRegistry());
diff --git a/include/llvm/Analysis/Dominators.h b/include/llvm/Analysis/Dominators.h
index d62a3ac..eb09b35 100644
--- a/include/llvm/Analysis/Dominators.h
+++ b/include/llvm/Analysis/Dominators.h
@@ -729,6 +729,8 @@ public:
   static char ID; // Pass ID, replacement for typeid
   DominatorTreeBase<BasicBlock>* DT;
 
+  static AnalysisID GetClassPassID();
+
   DominatorTree() : FunctionPass(ID) {
     initializeDominatorTreePass(*PassRegistry::getPassRegistry());
     DT = new DominatorTreeBase<BasicBlock>(false);
diff --git a/include/llvm/Analysis/IVUsers.h b/include/llvm/Analysis/IVUsers.h
index 9b98013..6baabe6 100644
--- a/include/llvm/Analysis/IVUsers.h
+++ b/include/llvm/Analysis/IVUsers.h
@@ -140,6 +140,8 @@ public:
   static char ID; // Pass ID, replacement for typeid
   IVUsers();
 
+  static AnalysisID GetClassPassID();
+
   Loop *getLoop() const { return L; }
 
   /// AddUsersIfInteresting - Inspect the specified Instruction.  If it is a
diff --git a/include/llvm/Analysis/LoopInfo.h b/include/llvm/Analysis/LoopInfo.h
index 6cdecf4..df106e4 100644
--- a/include/llvm/Analysis/LoopInfo.h
+++ b/include/llvm/Analysis/LoopInfo.h
@@ -553,6 +553,7 @@ class LoopInfo : public FunctionPass {
   LoopInfo(const LoopInfo &) LLVM_DELETED_FUNCTION;
 public:
   static char ID; // Pass identification, replacement for typeid
+  static AnalysisID GetClassPassID();
 
   LoopInfo() : FunctionPass(ID) {
     initializeLoopInfoPass(*PassRegistry::getPassRegistry());
diff --git a/include/llvm/Analysis/PostDominators.h b/include/llvm/Analysis/PostDominators.h
index d082297..1302bef 100644
--- a/include/llvm/Analysis/PostDominators.h
+++ b/include/llvm/Analysis/PostDominators.h
@@ -23,6 +23,7 @@ namespace llvm {
 ///
 struct PostDominatorTree : public FunctionPass {
   static char ID; // Pass identification, replacement for typeid
+  static AnalysisID GetClassPassID();
   DominatorTreeBase<BasicBlock>* DT;
 
   PostDominatorTree() : FunctionPass(ID) {
diff --git a/include/llvm/Analysis/RegionInfo.h b/include/llvm/Analysis/RegionInfo.h
index 69cc293..fbd7490 100644
--- a/include/llvm/Analysis/RegionInfo.h
+++ b/include/llvm/Analysis/RegionInfo.h
@@ -625,6 +625,7 @@ class RegionInfo : public FunctionPass {
 
 public:
   static char ID;
+  static AnalysisID GetClassPassID();
   explicit RegionInfo();
 
   ~RegionInfo();
diff --git a/include/llvm/Analysis/ScalarEvolution.h b/include/llvm/Analysis/ScalarEvolution.h
index f8f261f..7dbe53a 100644
--- a/include/llvm/Analysis/ScalarEvolution.h
+++ b/include/llvm/Analysis/ScalarEvolution.h
@@ -541,6 +541,7 @@ namespace llvm {
 
   public:
     static char ID; // Pass identification, replacement for typeid
+    static AnalysisID GetClassPassID();
     ScalarEvolution();
 
     LLVMContext &getContext() const { return F->getContext(); }
diff --git a/include/llvm/IR/DataLayout.h b/include/llvm/IR/DataLayout.h
index bfdb057..dd442dc 100644
--- a/include/llvm/IR/DataLayout.h
+++ b/include/llvm/IR/DataLayout.h
@@ -375,6 +375,7 @@ public:
   }
 
   static char ID; // Pass identification, replacement for typeid
+  static AnalysisID GetClassPassID();
 };
 
 /// StructLayout - used to lazily calculate structure layout information for a
diff --git a/include/llvm/Transforms/Scalar.h b/include/llvm/Transforms/Scalar.h
index e89759a..1d84662 100644
--- a/include/llvm/Transforms/Scalar.h
+++ b/include/llvm/Transforms/Scalar.h
@@ -221,6 +221,7 @@ extern char &BreakCriticalEdgesID;
 //
 Pass *createLoopSimplifyPass();
 extern char &LoopSimplifyID;
+const void* GetLoopSimplifyID();
 
 //===----------------------------------------------------------------------===//
 //
@@ -266,6 +267,7 @@ FunctionPass *createBlockPlacementPass();
 //
 Pass *createLCSSAPass();
 extern char &LCSSAID;
+const void* GetLCSSAID();
 
 //===----------------------------------------------------------------------===//
 //
diff --git a/lib/Analysis/AliasAnalysis.cpp b/lib/Analysis/AliasAnalysis.cpp
index 210b80a..e0f37be 100644
--- a/lib/Analysis/AliasAnalysis.cpp
+++ b/lib/Analysis/AliasAnalysis.cpp
@@ -42,6 +42,9 @@ using namespace llvm;
 // Register the AliasAnalysis interface, providing a nice name to refer to.
 INITIALIZE_ANALYSIS_GROUP(AliasAnalysis, "Alias Analysis", NoAA)
 char AliasAnalysis::ID = 0;
+const void *AliasAnalysis::GetClassPassID() {
+  return &ID;
+}
 
 //===----------------------------------------------------------------------===//
 // Default chaining methods
diff --git a/lib/Analysis/DominanceFrontier.cpp b/lib/Analysis/DominanceFrontier.cpp
index 7e4a89f..9629972 100644
--- a/lib/Analysis/DominanceFrontier.cpp
+++ b/lib/Analysis/DominanceFrontier.cpp
@@ -15,6 +15,9 @@
 using namespace llvm;
 
 char DominanceFrontier::ID = 0;
+AnalysisID DominanceFrontier::GetClassPassID() {
+  return &ID;
+}
 INITIALIZE_PASS_BEGIN(DominanceFrontier, "domfrontier",
                 "Dominance Frontier Construction", true, true)
 INITIALIZE_PASS_DEPENDENCY(DominatorTree)
diff --git a/lib/Analysis/IVUsers.cpp b/lib/Analysis/IVUsers.cpp
index b33e2cb..b93cb6f 100644
--- a/lib/Analysis/IVUsers.cpp
+++ b/lib/Analysis/IVUsers.cpp
@@ -39,6 +39,9 @@ INITIALIZE_PASS_DEPENDENCY(ScalarEvolution)
 INITIALIZE_PASS_END(IVUsers, "iv-users",
                       "Induction Variable Users", false, true)
 
+AnalysisID IVUsers::GetClassPassID() {
+  return &ID;
+}
 Pass *llvm::createIVUsersPass() {
   return new IVUsers();
 }
diff --git a/lib/Analysis/LoopInfo.cpp b/lib/Analysis/LoopInfo.cpp
index 4d4c627..f5dc2d0 100644
--- a/lib/Analysis/LoopInfo.cpp
+++ b/lib/Analysis/LoopInfo.cpp
@@ -49,6 +49,10 @@ INITIALIZE_PASS_BEGIN(LoopInfo, "loops", "Natural Loop Information", true, true)
 INITIALIZE_PASS_DEPENDENCY(DominatorTree)
 INITIALIZE_PASS_END(LoopInfo, "loops", "Natural Loop Information", true, true)
 
+AnalysisID LoopInfo::GetClassPassID() {
+  return &ID;
+}
+
 //===----------------------------------------------------------------------===//
 // Loop implementation
 //
diff --git a/lib/Analysis/PostDominators.cpp b/lib/Analysis/PostDominators.cpp
index 96804a0..0fcdda9 100644
--- a/lib/Analysis/PostDominators.cpp
+++ b/lib/Analysis/PostDominators.cpp
@@ -28,6 +28,9 @@ using namespace llvm;
 //===----------------------------------------------------------------------===//
 
 char PostDominatorTree::ID = 0;
+AnalysisID PostDominatorTree::GetClassPassID() {
+  return &ID;
+}
 INITIALIZE_PASS(PostDominatorTree, "postdomtree",
                 "Post-Dominator Tree Construction", true, true)
 
diff --git a/lib/Analysis/RegionInfo.cpp b/lib/Analysis/RegionInfo.cpp
index fad5074..29e095f 100644
--- a/lib/Analysis/RegionInfo.cpp
+++ b/lib/Analysis/RegionInfo.cpp
@@ -814,6 +814,9 @@ void RegionInfo::splitBlock(BasicBlock* NewBB, BasicBlock *OldBB)
 }
 
 char RegionInfo::ID = 0;
+AnalysisID RegionInfo::GetClassPassID() {
+  return &ID;
+}
 INITIALIZE_PASS_BEGIN(RegionInfo, "regions",
                 "Detect single entry single exit regions", true, true)
 INITIALIZE_PASS_DEPENDENCY(DominatorTree)
diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp
index 07d8329..3a06f97 100644
--- a/lib/Analysis/ScalarEvolution.cpp
+++ b/lib/Analysis/ScalarEvolution.cpp
@@ -120,6 +120,10 @@ INITIALIZE_PASS_END(ScalarEvolution, "scalar-evolution",
                 "Scalar Evolution Analysis", false, true)
 char ScalarEvolution::ID = 0;
 
+AnalysisID ScalarEvolution::GetClassPassID() {
+  return &ID;
+}
+
 //===----------------------------------------------------------------------===//
 //                           SCEV class definitions
 //===----------------------------------------------------------------------===//
diff --git a/lib/IR/DataLayout.cpp b/lib/IR/DataLayout.cpp
index f09de3a..5deaa02 100644
--- a/lib/IR/DataLayout.cpp
+++ b/lib/IR/DataLayout.cpp
@@ -36,6 +36,9 @@ using namespace llvm;
 // Register the default SparcV9 implementation...
 INITIALIZE_PASS(DataLayout, "datalayout", "Data Layout", false, true)
 char DataLayout::ID = 0;
+AnalysisID DataLayout::GetClassPassID() {
+  return &ID;
+}
 
 //===----------------------------------------------------------------------===//
 // Support for StructLayout
diff --git a/lib/IR/Dominators.cpp b/lib/IR/Dominators.cpp
index a1160cd..1f2c720 100644
--- a/lib/IR/Dominators.cpp
+++ b/lib/IR/Dominators.cpp
@@ -68,6 +68,10 @@ char DominatorTree::ID = 0;
 INITIALIZE_PASS(DominatorTree, "domtree",
                 "Dominator Tree Construction", true, true)
 
+AnalysisID DominatorTree::GetClassPassID() {
+  return &ID;
+}
+
 bool DominatorTree::runOnFunction(Function &F) {
   DT->recalculate(F);
   return false;
diff --git a/lib/Transforms/Utils/LCSSA.cpp b/lib/Transforms/Utils/LCSSA.cpp
index 2d1b166..41385a8 100644
--- a/lib/Transforms/Utils/LCSSA.cpp
+++ b/lib/Transforms/Utils/LCSSA.cpp
@@ -98,6 +98,7 @@ INITIALIZE_PASS_END(LCSSA, "lcssa", "Loop-Closed SSA Form Pass", false, false)
 
 Pass *llvm::createLCSSAPass() { return new LCSSA(); }
 char &llvm::LCSSAID = LCSSA::ID;
+const void* llvm::GetLCSSAID() { return &LCSSA::ID; }
 
 
 /// BlockDominatesAnExit - Return true if the specified block dominates at least
diff --git a/lib/Transforms/Utils/LoopSimplify.cpp b/lib/Transforms/Utils/LoopSimplify.cpp
index 37819cc..9f0e60b 100644
--- a/lib/Transforms/Utils/LoopSimplify.cpp
+++ b/lib/Transforms/Utils/LoopSimplify.cpp
@@ -120,6 +120,7 @@ INITIALIZE_PASS_END(LoopSimplify, "loop-simplify",
 
 // Publicly exposed interface to pass...
 char &llvm::LoopSimplifyID = LoopSimplify::ID;
+const void* llvm::GetLoopSimplifyID() { return &LoopSimplify::ID; }
 Pass *llvm::createLoopSimplifyPass() { return new LoopSimplify(); }
 
 /// runOnLoop - Run down all loops in the CFG (recursively, but we could do
-- 
1.7.8.3



More information about the llvm-commits mailing list