From efd47ba3ac178562d98a36a3538f89e3adac759f Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Wed, 22 Oct 2003 03:35:34 +0000 Subject: Implement FunctionResolve/2003-10-21-GlobalResolveHack.ll git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@9363 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/IPO/FunctionResolution.cpp | 36 +++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/Transforms/IPO/FunctionResolution.cpp b/lib/Transforms/IPO/FunctionResolution.cpp index ecabc692b4..5030e26dc5 100644 --- a/lib/Transforms/IPO/FunctionResolution.cpp +++ b/lib/Transforms/IPO/FunctionResolution.cpp @@ -25,6 +25,7 @@ #include "llvm/Pass.h" #include "llvm/iOther.h" #include "llvm/Constants.h" +#include "llvm/Target/TargetData.h" #include "llvm/Assembly/Writer.h" #include "Support/Statistic.h" #include @@ -34,6 +35,10 @@ namespace { Statistic<> NumGlobals("funcresolve", "Number of global variables resolved"); struct FunctionResolvingPass : public Pass { + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired(); + } + bool run(Module &M); }; RegisterOpt X("funcresolve", "Resolve Functions"); @@ -125,7 +130,7 @@ static bool ResolveGlobalVariables(Module &M, return Changed; } -static bool ProcessGlobalsWithSameName(Module &M, +static bool ProcessGlobalsWithSameName(Module &M, TargetData &TD, std::vector &Globals) { assert(!Globals.empty() && "Globals list shouldn't be empty here!"); @@ -202,6 +207,31 @@ static bool ProcessGlobalsWithSameName(Module &M, if (!Concrete) Concrete = Globals[0]; + else if (GlobalVariable *GV = dyn_cast(Concrete)) { + // Handle special case hack to change globals if it will make their types + // happier in the long run. The situation we do this is intentionally + // extremely limited. + if (GV->use_empty() && GV->hasInitializer() && + GV->getInitializer()->isNullValue()) { + // Check to see if there is another (external) global with the same size + // and a non-empty use-list. If so, we will make IT be the real + // implementation. + unsigned TS = TD.getTypeSize(Concrete->getType()->getElementType()); + for (unsigned i = 0, e = Globals.size(); i != e; ++i) + if (Globals[i] != Concrete && !Globals[i]->use_empty() && + isa(Globals[i]) && + TD.getTypeSize(Globals[i]->getType()->getElementType()) == TS) { + // At this point we want to replace Concrete with Globals[i]. Make + // concrete external, and Globals[i] have an initializer. + GlobalVariable *NGV = cast(Globals[i]); + const Type *ElTy = NGV->getType()->getElementType(); + NGV->setInitializer(Constant::getNullValue(ElTy)); + cast(Concrete)->setInitializer(0); + Concrete = NGV; + break; + } + } + } if (isFunction) return ResolveFunctions(M, Globals, cast(Concrete)); @@ -236,12 +266,14 @@ bool FunctionResolvingPass::run(Module &M) { bool Changed = false; + TargetData &TD = getAnalysis(); + // Now we have a list of all functions with a particular name. If there is // more than one entry in a list, merge the functions together. // for (std::map >::iterator I = Globals.begin(), E = Globals.end(); I != E; ++I) - Changed |= ProcessGlobalsWithSameName(M, I->second); + Changed |= ProcessGlobalsWithSameName(M, TD, I->second); // Now loop over all of the globals, checking to see if any are trivially // dead. If so, remove them now. -- cgit v1.2.3