* Fix extract to work with constant pointer refs correctly
authorChris Lattner <sabre@nondot.org>
Sat, 12 Oct 2002 20:50:16 +0000 (20:50 +0000)
committerChris Lattner <sabre@nondot.org>
Sat, 12 Oct 2002 20:50:16 +0000 (20:50 +0000)
* Extract makes all global vars external, so they don't have initializers

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@4121 91177308-0d34-0410-b5e6-96231b3b80d8

tools/extract/extract.cpp
tools/llvm-extract/llvm-extract.cpp

index 5df4cb283543258d1996166a21586200c0588a2c..fd865419c9d586b31b492c814bbd0b314245bbdc 100644 (file)
@@ -30,14 +30,16 @@ struct FunctionExtractorPass : public Pass {
   bool run(Module &M) {
     // Mark all global variables to be internal
     for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I)
-      if (!I->isExternal())
-        I->setInternalLinkage(true);
+      if (!I->isExternal()) {
+        I->setInitializer(0);  // Make all variables external
+        I->setInternalLinkage(false); // Make sure it's not internal
+      }
 
     Function *Named = 0;
 
     // Loop over all of the functions in the module, dropping all references in
     // functions that are not the named function.
-    for (Module::iterator I = M.begin(), E = M.end(); I != E;)
+    for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
       // Check to see if this is the named function!
       if (I->getName() == ExtractFunc && !I->isExternal()) {
         if (Named) {                            // Two functions, same name?
@@ -51,41 +53,59 @@ struct FunctionExtractorPass : public Pass {
 
         // Make sure it's globally accessable...
         Named->setInternalLinkage(false);
-
-        // Remove the named function from the module.
-        M.getFunctionList().remove(I);
-      } else {
-        // Nope it's not the named function, delete the body of the function
-        I->dropAllReferences();
-        ++I;
       }
-
-    // All of the functions that still have uses now must be used by global
-    // variables or the named function.  Loop through them and create a new,
-    // external function for the used ones... making all uses point to the new
-    // functions.
+    
+    if (Named == 0) {
+      std::cerr << "Warning: Function '" << ExtractFunc << "' not found!\n";
+      return false;
+    }
+    
+    // All of the functions may be used by global variables or the named
+    // function.  Loop through them and create a new, external functions that
+    // can be "used", instead of ones with bodies.
+    //
     std::vector<Function*> NewFunctions;
     
-    for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
-      if (!I->use_empty()) {
+    Function *Last = &M.back();  // Figure out where the last real fn is...
+
+    for (Module::iterator I = M.begin(); ; ++I) {
+      if (I->getName() != ExtractFunc) {
         Function *New = new Function(I->getFunctionType(), false, I->getName());
-        I->replaceAllUsesWith(New);
+        I->setName("");  // Remove Old name
+
+        // If it's not the named function, delete the body of the function
+        I->dropAllReferences();
+
+        M.getFunctionList().push_back(New);
         NewFunctions.push_back(New);
       }
+
+      if (&*I == Last) break;  // Stop after processing the last function
+    }
+
+    // Now that we have replacements all set up, loop through the module,
+    // deleting the old functions, replacing them with the newly created
+    // functions.
+    if (!NewFunctions.empty()) {
+      unsigned FuncNum = 0;
+      Module::iterator I = M.begin();
+      do {
+        if (I->getName() != ExtractFunc) {
+          // Make everything that uses the old function use the new dummy fn
+          I->replaceAllUsesWith(NewFunctions[FuncNum++]);
+          
+          Function *Old = I;
+          ++I;  // Move the iterator to the new function
+
+          // Delete the old function!
+          M.getFunctionList().erase(Old);
+
+        } else {
+          ++I;  // Skip the function we are extracting
+        }
+      } while (&*I != NewFunctions[0]);
+    }
     
-    // Now the module only has unused functions with their references dropped.
-    // Delete them all now!
-    M.getFunctionList().clear();
-
-    // Re-insert the named function...
-    if (Named)
-      M.getFunctionList().push_back(Named);
-    else
-      std::cerr << "Warning: Function '" << ExtractFunc << "' not found!\n";
-    
-    // Insert all of the function stubs...
-    M.getFunctionList().insert(M.end(), NewFunctions.begin(),
-                               NewFunctions.end());
     return true;
   }
 };
@@ -109,6 +129,7 @@ int main(int argc, char **argv) {
   PassManager Passes;
   Passes.add(new FunctionExtractorPass());
   Passes.add(createGlobalDCEPass());              // Delete unreachable globals
+  Passes.add(createFunctionResolvingPass());      // Delete prototypes
   Passes.add(createConstantMergePass());          // Merge dup global constants
   Passes.add(createDeadTypeEliminationPass());    // Remove dead types...
   Passes.add(new WriteBytecodePass(&std::cout));  // Write bytecode to file...
index 5df4cb283543258d1996166a21586200c0588a2c..fd865419c9d586b31b492c814bbd0b314245bbdc 100644 (file)
@@ -30,14 +30,16 @@ struct FunctionExtractorPass : public Pass {
   bool run(Module &M) {
     // Mark all global variables to be internal
     for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; ++I)
-      if (!I->isExternal())
-        I->setInternalLinkage(true);
+      if (!I->isExternal()) {
+        I->setInitializer(0);  // Make all variables external
+        I->setInternalLinkage(false); // Make sure it's not internal
+      }
 
     Function *Named = 0;
 
     // Loop over all of the functions in the module, dropping all references in
     // functions that are not the named function.
-    for (Module::iterator I = M.begin(), E = M.end(); I != E;)
+    for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
       // Check to see if this is the named function!
       if (I->getName() == ExtractFunc && !I->isExternal()) {
         if (Named) {                            // Two functions, same name?
@@ -51,41 +53,59 @@ struct FunctionExtractorPass : public Pass {
 
         // Make sure it's globally accessable...
         Named->setInternalLinkage(false);
-
-        // Remove the named function from the module.
-        M.getFunctionList().remove(I);
-      } else {
-        // Nope it's not the named function, delete the body of the function
-        I->dropAllReferences();
-        ++I;
       }
-
-    // All of the functions that still have uses now must be used by global
-    // variables or the named function.  Loop through them and create a new,
-    // external function for the used ones... making all uses point to the new
-    // functions.
+    
+    if (Named == 0) {
+      std::cerr << "Warning: Function '" << ExtractFunc << "' not found!\n";
+      return false;
+    }
+    
+    // All of the functions may be used by global variables or the named
+    // function.  Loop through them and create a new, external functions that
+    // can be "used", instead of ones with bodies.
+    //
     std::vector<Function*> NewFunctions;
     
-    for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
-      if (!I->use_empty()) {
+    Function *Last = &M.back();  // Figure out where the last real fn is...
+
+    for (Module::iterator I = M.begin(); ; ++I) {
+      if (I->getName() != ExtractFunc) {
         Function *New = new Function(I->getFunctionType(), false, I->getName());
-        I->replaceAllUsesWith(New);
+        I->setName("");  // Remove Old name
+
+        // If it's not the named function, delete the body of the function
+        I->dropAllReferences();
+
+        M.getFunctionList().push_back(New);
         NewFunctions.push_back(New);
       }
+
+      if (&*I == Last) break;  // Stop after processing the last function
+    }
+
+    // Now that we have replacements all set up, loop through the module,
+    // deleting the old functions, replacing them with the newly created
+    // functions.
+    if (!NewFunctions.empty()) {
+      unsigned FuncNum = 0;
+      Module::iterator I = M.begin();
+      do {
+        if (I->getName() != ExtractFunc) {
+          // Make everything that uses the old function use the new dummy fn
+          I->replaceAllUsesWith(NewFunctions[FuncNum++]);
+          
+          Function *Old = I;
+          ++I;  // Move the iterator to the new function
+
+          // Delete the old function!
+          M.getFunctionList().erase(Old);
+
+        } else {
+          ++I;  // Skip the function we are extracting
+        }
+      } while (&*I != NewFunctions[0]);
+    }
     
-    // Now the module only has unused functions with their references dropped.
-    // Delete them all now!
-    M.getFunctionList().clear();
-
-    // Re-insert the named function...
-    if (Named)
-      M.getFunctionList().push_back(Named);
-    else
-      std::cerr << "Warning: Function '" << ExtractFunc << "' not found!\n";
-    
-    // Insert all of the function stubs...
-    M.getFunctionList().insert(M.end(), NewFunctions.begin(),
-                               NewFunctions.end());
     return true;
   }
 };
@@ -109,6 +129,7 @@ int main(int argc, char **argv) {
   PassManager Passes;
   Passes.add(new FunctionExtractorPass());
   Passes.add(createGlobalDCEPass());              // Delete unreachable globals
+  Passes.add(createFunctionResolvingPass());      // Delete prototypes
   Passes.add(createConstantMergePass());          // Merge dup global constants
   Passes.add(createDeadTypeEliminationPass());    // Remove dead types...
   Passes.add(new WriteBytecodePass(&std::cout));  // Write bytecode to file...