From ea2294a498aaafcd32ba1d3714370b220020494c Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 19 Apr 2003 00:15:27 +0000 Subject: [PATCH] Implement: FunctionResolve/2003-04-18-ForwardDeclGlobal.ll git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@5816 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/IPO/FunctionResolution.cpp | 82 +++++++++++------------ 1 file changed, 39 insertions(+), 43 deletions(-) diff --git a/lib/Transforms/IPO/FunctionResolution.cpp b/lib/Transforms/IPO/FunctionResolution.cpp index 932cdf46e89..3e530e07081 100644 --- a/lib/Transforms/IPO/FunctionResolution.cpp +++ b/lib/Transforms/IPO/FunctionResolution.cpp @@ -201,30 +201,23 @@ static bool ResolveGlobalVariables(Module &M, "Concrete version should be an array type!"); // Get the type of the things that may be resolved to us... - const Type *AETy = - cast(Concrete->getType()->getElementType())->getElementType(); - - std::vector Args; - Args.push_back(Constant::getNullValue(Type::LongTy)); - Args.push_back(Constant::getNullValue(Type::LongTy)); - Constant *Replacement = - ConstantExpr::getGetElementPtr(ConstantPointerRef::get(Concrete), Args); - + const ArrayType *CATy =cast(Concrete->getType()->getElementType()); + const Type *AETy = CATy->getElementType(); + + Constant *CCPR = ConstantPointerRef::get(Concrete); + for (unsigned i = 0; i != Globals.size(); ++i) if (Globals[i] != Concrete) { GlobalVariable *Old = cast(Globals[i]); - if (Old->getType()->getElementType() != AETy) { + const ArrayType *OATy = cast(Old->getType()->getElementType()); + if (OATy->getElementType() != AETy || OATy->getNumElements() != 0) { std::cerr << "WARNING: Two global variables exist with the same name " << "that cannot be resolved!\n"; return false; } - // In this case, Old is a pointer to T, Concrete is a pointer to array of - // T. Because of this, replace all uses of Old with a constantexpr - // getelementptr that returns the address of the first element of the - // array. - // - Old->replaceAllUsesWith(Replacement); + Old->replaceAllUsesWith(ConstantExpr::getCast(CCPR, Old->getType())); + // Since there are no uses of Old anymore, remove it from the module. M.getGlobalList().erase(Old); @@ -239,7 +232,6 @@ static bool ProcessGlobalsWithSameName(Module &M, assert(!Globals.empty() && "Globals list shouldn't be empty here!"); bool isFunction = isa(Globals[0]); // Is this group all functions? - bool Changed = false; GlobalValue *Concrete = 0; // The most concrete implementation to resolve to assert((isFunction ^ isa(Globals[0])) && @@ -271,32 +263,36 @@ static bool ProcessGlobalsWithSameName(Module &M, } else { Concrete = F; } - ++i; } else { // For global variables, we have to merge C definitions int A[][4] with - // int[6][4] + // int[6][4]. A[][4] is represented as A[0][4] by the CFE. GlobalVariable *GV = cast(Globals[i]); - if (Concrete == 0) { - if (isa(GV->getType()->getElementType())) - Concrete = GV; - } else { // Must have different types... one is an array of the other? - const ArrayType *AT = - dyn_cast(GV->getType()->getElementType()); - - // If GV is an array of Concrete, then GV is the array. - if (AT && AT->getElementType() == Concrete->getType()->getElementType()) - Concrete = GV; - else { - // Concrete must be an array type, check to see if the element type of - // concrete is already GV. - AT = cast(Concrete->getType()->getElementType()); - if (AT->getElementType() != GV->getType()->getElementType()) - Concrete = 0; // Don't know how to handle it! + if (!isa(GV->getType()->getElementType())) { + Concrete = 0; + break; // Non array's cannot be compatible with other types. + } else if (Concrete == 0) { + Concrete = GV; + } else { + // Must have different types... allow merging A[0][4] w/ A[6][4] if + // A[0][4] is external. + const ArrayType *NAT = cast(GV->getType()->getElementType()); + const ArrayType *CAT = + cast(Concrete->getType()->getElementType()); + + if (NAT->getElementType() != CAT->getElementType()) { + Concrete = 0; // Non-compatible types + break; + } else if (NAT->getNumElements() == 0 && GV->isExternal()) { + // Concrete remains the same + } else if (CAT->getNumElements() == 0 && Concrete->isExternal()) { + Concrete = GV; // Concrete becomes GV + } else { + Concrete = 0; // Cannot merge these types... + break; } } - - ++i; } + ++i; } if (Globals.size() > 1) { // Found a multiply defined global... @@ -305,23 +301,23 @@ static bool ProcessGlobalsWithSameName(Module &M, // uses to use it instead. // if (!Concrete) { - std::cerr << "WARNING: Found function types that are not compatible:\n"; + std::cerr << "WARNING: Found global types that are not compatible:\n"; for (unsigned i = 0; i < Globals.size(); ++i) { std::cerr << "\t" << Globals[i]->getType()->getDescription() << " %" << Globals[i]->getName() << "\n"; } std::cerr << " No linkage of globals named '" << Globals[0]->getName() << "' performed!\n"; - return Changed; + return false; } if (isFunction) - return Changed | ResolveFunctions(M, Globals, cast(Concrete)); + return ResolveFunctions(M, Globals, cast(Concrete)); else - return Changed | ResolveGlobalVariables(M, Globals, - cast(Concrete)); + return ResolveGlobalVariables(M, Globals, + cast(Concrete)); } - return Changed; + return false; } bool FunctionResolvingPass::run(Module &M) { -- 2.40.0