<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
  <meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type">
  <title></title>
</head>
<body bgcolor="#ffffff" text="#000000">
Hi,<br>
<br>
Reid Spencer wrote:
<blockquote cite="mid1155762430.10524.264.camel@bashful.x10sys.com"
 type="cite">
  <blockquote type="cite">
    <pre wrap="">That's interesting! So, one only needs to add a 2-arg function called  
RunOptimizations to the module (can't check it right now)?
    </pre>
  </blockquote>
  <pre wrap=""><!---->
That is correct. That function and only that function will be called.
What happens in that function is up to you :)
  </pre>
</blockquote>
So, I tried this the last two days, but to no avail. I first wrote the
following three files to introduce the RunOptimizations-symbol (adapted
from
<a class="moz-txt-link-freetext" href="http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html#faq-32.8">http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html#faq-32.8</a>):<br>
<br>
a) Loader.h<br>
<br>
#ifndef LOADER_H<br>
#define LOADER_H<br>
<br>
#ifdef __cplusplus<br>
#include "llvm/PassManager.h"<br>
using namespace llvm;<br>
#else<br>
typedef struct PassManager PassManager;<br>
#endif<br>
 <br>
#ifdef __cplusplus<br>
extern "C" {<br>
  extern void RunOptimizations(PassManager*,...);   /* ANSI C
prototypes */<br>
  extern PassManager* load_weaver_passes(PassManager*);<br>
}<br>
#endif<br>
<br>
#endif<br>
<br>
<br>
b) c-Loader.c<br>
<br>
#include "loader/Loader.h"<br>
<br>
void RunOptimizations(PassManager* mgr,...){<br>
  load_weaver_passes(mgr);<br>
}<br>
<br>
<br>
c) Loader.cpp<br>
<br>
#include "loader/Loader.h"<br>
#include "matcher/Matcher.h"<br>
#include "reifier/Reifier.h"<br>
<br>
PassManager* load_weaver_passes(PassManager* mgr){<br>
  mgr->add(createFirstPass());<br>
  mgr->add(createSecondPass());<br>
<br>
  return mgr;<br>
}<br>
<br>
In short, the C part (RunOptimizations) hands its first argument over
to a global C++ method to add my passes.<br>
<br>
When using this machinery with llvm-ld (Slackware 10.2, GCC 3.3.6 and
LLVM 1.8a), my passes are indeed loaded in and the PassManager attempts
to run on the processed module. Then, I get the following:<br>
<br>
Program received signal SIGSEGV, Segmentation fault.<br>
0xb7f16abf in __dynamic_cast () from /usr/lib/libstdc++.so.5<br>
<br>
#0  0xb7ea9abf in __dynamic_cast () from /usr/lib/libstdc++.so.5<br>
#1  0x0843f19d in llvm::PMDebug::PrintArgumentInformation (P=0x85e3b00)
at /.../llvm/lib/VMCore/Pass.cpp:132<br>
#2  0x0843f1fc in llvm::PMDebug::PrintArgumentInformation (P=0x85ca030)
at /.../llvm/lib/VMCore/Pass.cpp:134<br>
#3  0x0844e3b8 in llvm::PMDebug::PerformPassStartupStuff (P=0x85ca030)
at PassManagerT.h:66<br>
#4  0x08444146 in llvm::PassManagerT<llvm::MTraits>::runOnUnit
(this=0x85ca048, M=0x85bf330) at PassManagerT.h:280<br>
#5  0x0843eb26 in llvm::ModulePassManager::runOnModule (this=0x85ca030,
M=@0x85bf330) at PassManagerT.h:905<br>
#6  0x0843eebf in llvm::PassManager::run (this=0xbfe36400,
M=@0x85bf330) at /.../llvm/lib/VMCore/Pass.cpp:85<br>
#7  0x082a0361 in llvm::Optimize (M=0x85bf330) at
/.../llvm/tools/llvm-ld/Optimize.cpp:189<br>
#8  0x082a7161 in main (argc=14, argv=0xbfe365e4, envp=0xbfe36620) at
/.../llvm/tools/llvm-ld/llvm-ld.cpp:467<br>
<br>
The backtrace led me to this code snippet (lib/VMCore/Pass.cpp near
line 132):<br>
<br>
void PMDebug::PrintArgumentInformation(const Pass *P) {<br>
  // Print out passes in pass manager...<br>
  if (const AnalysisResolver *PM = dynamic_cast<const
AnalysisResolver*>(P)) { //<-- !!!!!!! ERROR !!!!!!!<br>
    for (unsigned i = 0, e = PM->getNumContainedPasses(); i != e;
++i)<br>
      PrintArgumentInformation(PM->getContainedPass(i));<br>
<br>
  } else {  // Normal pass.  Print argument information...<br>
    // Print out arguments for registered passes that are
_optimizations_<br>
    if (const PassInfo *PI = P->getPassInfo())<br>
      if (PI->getPassType() & PassInfo::Optimization)<br>
        std::cerr << " -" << PI->getPassArgument();<br>
  }<br>
}<br>
<br>
While I could verify (using GDB/DDD) that my passes were loaded
perfectly in load_weaver_pass, once they got on the line marked with
ERROR the pointer to their vtable suddenly was inaccessible. This made
dynamic_cast crash. The hardcoded passes, loaded in before mine by
llvm-ld, had no problems whatsoever. For some reason, some memory
allocated in my C/C++ bridge is just not accessible anymore by llvm-ld,
but I don't know why ...<br>
<br>
At long last, I decided to port opt's pass loading mechanism to llvm-ld
to see if this would solve things in my case (despite its limitations).
And it did! I attached my hack (with uncommented existing loading
mechanism) in case someone else encounters the same problems. Maybe
some extra argument switch for llvm-ld could allow user-switchable
coexistence of both loading mechanisms?<br>
<br>
Has anyone else experimented with llvm-ld yet? Did the same problem
arise?<br>
<br>
Kind regards,<br>
<br>
Bram Adams<br>
GH-SEL, INTEC, Ghent University<br>
</body>
</html>