aboutsummaryrefslogtreecommitdiffstats
path: root/tools/extract
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2002-10-12 20:50:16 +0000
committerChris Lattner <sabre@nondot.org>2002-10-12 20:50:16 +0000
commit68ed318d330fd3c00761cc1d5f613e981905f588 (patch)
tree430272bb2cd7f1a7e223e07412b85c3f6accc1b2 /tools/extract
parent3383b1d3bb3bdbc39a0a057d83f0db26ea4440b0 (diff)
downloadexternal_llvm-68ed318d330fd3c00761cc1d5f613e981905f588.zip
external_llvm-68ed318d330fd3c00761cc1d5f613e981905f588.tar.gz
external_llvm-68ed318d330fd3c00761cc1d5f613e981905f588.tar.bz2
* Fix extract to work with constant pointer refs correctly
* 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
Diffstat (limited to 'tools/extract')
-rw-r--r--tools/extract/extract.cpp83
1 files changed, 52 insertions, 31 deletions
diff --git a/tools/extract/extract.cpp b/tools/extract/extract.cpp
index 5df4cb2..fd86541 100644
--- a/tools/extract/extract.cpp
+++ b/tools/extract/extract.cpp
@@ -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...