[llvm-commits] CVS: llvm/tools/bugpoint/CodeGeneratorBug.cpp

Misha Brukman brukman at cs.uiuc.edu
Mon Jul 28 16:08:02 PDT 2003


Changes in directory llvm/tools/bugpoint:

CodeGeneratorBug.cpp updated: 1.3 -> 1.4

---
Log message:

Implemented cleanups as suggested by Chris:
* Use Module::getNamedFunction() to delete "main" instead of using a loop
* Compare function pointers instead of function names to determine equivalence
* Simplified creation of a 2-element vector containing zeroes
* Manually performed LICM on code
* Added an abort() in case a function we're considering occurs in something that
  is not an instruction
* Use DEBUG() around code sections instead of just in a statement in a loop,
  because GCC's DCE may not be good enough to completely remove it in a release
  build
* Print out a command that can be directly copied-and-pasted to re-execute
* Instead of just checking if a symbol begins with a dot and fixing it
  accordingly, use Mangler and fix all the problems (invalid chars in C symbol
  names) entirely
* The new `main' function has external linkage 


---
Diffs of the changes:

Index: llvm/tools/bugpoint/CodeGeneratorBug.cpp
diff -u llvm/tools/bugpoint/CodeGeneratorBug.cpp:1.3 llvm/tools/bugpoint/CodeGeneratorBug.cpp:1.4
--- llvm/tools/bugpoint/CodeGeneratorBug.cpp:1.3	Mon Jul 28 14:16:14 2003
+++ llvm/tools/bugpoint/CodeGeneratorBug.cpp	Mon Jul 28 16:07:39 2003
@@ -16,6 +16,7 @@
 #include "llvm/Module.h"
 #include "llvm/Pass.h"
 #include "llvm/Analysis/Verifier.h"
+#include "llvm/Support/Mangler.h"
 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
 #include "llvm/Transforms/Utils/Cloning.h"
 #include "llvm/Transforms/Utils/Linker.h"
@@ -94,8 +95,8 @@
   // (called or taken address of), and make them call the JIT wrapper instead
   if (BD.isExecutingJIT()) {
     // Must delete `main' from Safe module if it has it
-    for (Module::iterator I=SafeModule->begin(), E=SafeModule->end();I!=E;++I)
-      if (I->getName() == "main") DeleteFunctionBody(I);
+    Function *safeMain = SafeModule->getNamedFunction("main");
+    DeleteFunctionBody(safeMain);
 
     // Add an external function "getPointerToNamedFunction" that JIT provides
     // Prototype: void *getPointerToNamedFunction(const char* Name)
@@ -103,17 +104,15 @@
     Params.push_back(PointerType::get(Type::SByteTy)); // std::string&
     FunctionType *resolverTy = FunctionType::get(PointerType::get(Type::VoidTy),
                                                  Params, false /* isVarArg */);
-    const std::string ResolverFunctionName = "getPointerToNamedFunction";
     Function *resolverFunc = new Function(resolverTy,
                                           GlobalValue::ExternalLinkage,
-                                          ResolverFunctionName,
+                                          "getPointerToNamedFunction",
                                           SafeModule);
 
     // Use the function we just added to get addresses of functions we need
     // Iterate over the global declarations in the Safe module
     for (Module::iterator F=SafeModule->begin(),E=SafeModule->end(); F!=E; ++F){
-      if (F->isExternal() && F->use_begin() != F->use_end() &&
-          F->getName() != ResolverFunctionName) {
+      if (F->isExternal() && !F->use_empty() && &(*F) != resolverFunc) {
         // If it has a non-zero use list,
         // 1. Add a string constant with its name to the global file
         // The correct type is `const [ NUM x sbyte ]' where NUM is length of
@@ -129,26 +128,23 @@
 
         // 2. Use `GetElementPtr *funcName, 0, 0' to convert the string to an
         // sbyte* so it matches the signature of the resolver function.
-        Constant *Zero = Constant::getNullValue(Type::LongTy);
-        std::vector<Constant*> GEPargs;
-        GEPargs.push_back(Zero);
-        GEPargs.push_back(Zero);
+        std::vector<Constant*> GEPargs(2, Constant::getNullValue(Type::LongTy));
 
         // 3. Replace all uses of `func' with calls to resolver by:
         // (a) Iterating through the list of uses of this function
         // (b) Insert a cast instruction in front of each use
         // (c) Replace use of old call with new call
 
-        // Insert code at the beginning of the function
+        // GetElementPtr *funcName, ulong 0, ulong 0
+        Value *GEP =
+          ConstantExpr::getGetElementPtr(ConstantPointerRef::get(funcName),
+                                         GEPargs);
+        std::vector<Value*> ResolverArgs;
+        ResolverArgs.push_back(GEP);
 
+        // Insert code at the beginning of the function
         for (Value::use_iterator i=F->use_begin(), e=F->use_end(); i!=e; ++i) {
           if (Instruction* Inst = dyn_cast<Instruction>(*i)) {
-            // GetElementPtr *funcName, ulong 0, ulong 0
-            Value *GEP =
-              ConstantExpr::getGetElementPtr(ConstantPointerRef::get(funcName),
-                                             GEPargs);
-            std::vector<Value*> ResolverArgs;
-            ResolverArgs.push_back(GEP);
             // call resolver(GetElementPtr...)
             CallInst *resolve = new CallInst(resolverFunc, ResolverArgs, 
                                              "resolver", Inst);
@@ -158,27 +154,32 @@
                            "", Inst);
             // actually use the resolved function
             Inst->replaceUsesOfWith(F, castResolver);
-
-            //BasicBlock::iterator ii(Inst);
-            //ReplaceInstWithValue(Inst->getParent()->getInstList(),
-            //                     ii, ResolverResult);
+          } else {
+            // FIXME: need to take care of cases where a function is used that
+            // is not an instruction, e.g. global variable initializer...
+            std::cerr << "Non-instruction is using an external function!\n";
+            abort();
           }
         }
       }
     }
   }
 
-  DEBUG(std::cerr << "Safe module:\n");
-  for (Module::iterator I = SafeModule->begin(), E = SafeModule->end();I!=E;++I)
-    if (!I->isExternal()) DEBUG(std::cerr << "\t" << I->getName() << "\n");
-  for (Module::giterator I=SafeModule->gbegin(),E = SafeModule->gend();I!=E;++I)
-    if (!I->isExternal()) DEBUG(std::cerr << "\t" << I->getName() << "\n");
-
-  DEBUG(std::cerr << "Test module:\n");
-  for (Module::iterator  I =TestModule->begin(),E = TestModule->end(); I!=E;++I)
-    if (!I->isExternal()) DEBUG(std::cerr << "\t" << I->getName() << "\n");
-  for (Module::giterator I=TestModule->gbegin(),E = TestModule->gend();I!=E;++I)
-    if (!I->isExternal()) DEBUG(std::cerr << "\t" << I->getName() << "\n");
+  DEBUG(std::cerr << "Safe module:\n";
+        typedef Module::iterator MI;
+        typedef Module::giterator MGI;
+
+        for (MI I = SafeModule->begin(), E = SafeModule->end(); I != E; ++I)
+          if (!I->isExternal()) std::cerr << "\t" << I->getName() << "\n";
+        for (MGI I = SafeModule->gbegin(), E = SafeModule->gend(); I!=E; ++I)
+          if (!I->isExternal()) std::cerr << "\t" << I->getName() << "\n";
+
+        std::cerr << "Test module:\n";
+        for (MI I = TestModule->begin(), E = TestModule->end(); I != E; ++I)
+          if (!I->isExternal()) std::cerr << "\t" << I->getName() << "\n";
+        for (MGI I=TestModule->gbegin(),E = TestModule->gend(); I!= E; ++I)
+          if (!I->isExternal()) std::cerr << "\t" << I->getName() << "\n";
+        );
 
   // Write out the bytecode to be sent to CBE
   std::string SafeModuleBC = getUniqueFilename("bugpoint.safe.bc");
@@ -226,7 +227,8 @@
   int Result =  BD.diffProgram(TestModuleBC, SharedObject, false);
   if (KeepFiles) {
     std::cout << "You can reproduce the problem with the command line: \n"
-              << "lli (or llc) -load " << SharedObject << " " << TestModuleBC
+              << (BD.isExecutingJIT() ? "lli" : "llc")
+              << " -load " << SharedObject << " " << TestModuleBC
               << "\n";
   } else {
     removeFile(TestModuleBC);
@@ -253,13 +255,10 @@
 
       std::string SymName = V.getName();
 
-      // If the symbol starts with a '.', replace it with 'x'
-      // This solves the problem of not being able to find symbols in an .so
-      // file when those symbol names start with '.'
-      if (SymName[0] == '.') { 
-        SymName[0] = 'x';
-        V.setName(SymName);
-      }
+      // Use the Mangler facility to make symbol names that will be valid in
+      // shared objects.
+      SymName = Mangler::makeNameProper(SymName);
+      V.setName(SymName);
 
       if (SymbolNames.count(SymName) == 0) {
         DEBUG(std::cerr << "Disambiguator: adding " << SymName
@@ -322,7 +321,7 @@
     oldMain->setName("old_main");
     // Create a NEW `main' function with same type
     Function *newMain = new Function(oldMain->getFunctionType(), 
-                                     GlobalValue::InternalLinkage,
+                                     GlobalValue::ExternalLinkage,
                                      "main", Program);
     // Call the old main function and return its result
     BasicBlock *BB = new BasicBlock("entry", newMain);
@@ -343,7 +342,6 @@
     // Add the return instruction to the BasicBlock
     BB->getInstList().push_back(ret);
   }
-
 
   // Do the reduction...
   ReduceMisCodegenFunctions(*this).reduceList(MisCodegenFunctions);





More information about the llvm-commits mailing list