diff options
Diffstat (limited to 'llvm/lib/IR')
-rw-r--r-- | llvm/lib/IR/AsmWriter.cpp | 8 | ||||
-rw-r--r-- | llvm/lib/IR/Core.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/IR/Globals.cpp | 46 | ||||
-rw-r--r-- | llvm/lib/IR/Value.cpp | 28 | ||||
-rw-r--r-- | llvm/lib/IR/Verifier.cpp | 6 |
5 files changed, 37 insertions, 53 deletions
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index 3cbb1d10497..0fef0d0a188 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -1493,10 +1493,16 @@ void AssemblyWriter::printAlias(const GlobalAlias *GA) { PrintLinkage(GA->getLinkage(), Out); + PointerType *Ty = GA->getType(); const Constant *Aliasee = GA->getAliasee(); + if (!Aliasee || Ty != Aliasee->getType()) { + if (unsigned AddressSpace = Ty->getAddressSpace()) + Out << "addrspace(" << AddressSpace << ") "; + TypePrinter.print(Ty->getElementType(), Out); + Out << ", "; + } if (!Aliasee) { - TypePrinter.print(GA->getType(), Out); Out << " <<NULL ALIASEE>>"; } else { writeOperand(Aliasee, !isa<ConstantExpr>(Aliasee)); diff --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp index 40c1c70257e..100c9def185 100644 --- a/llvm/lib/IR/Core.cpp +++ b/llvm/lib/IR/Core.cpp @@ -1491,7 +1491,7 @@ LLVMValueRef LLVMAddAlias(LLVMModuleRef M, LLVMTypeRef Ty, LLVMValueRef Aliasee, auto *PTy = cast<PointerType>(unwrap(Ty)); return wrap(new GlobalAlias( PTy->getElementType(), GlobalValue::ExternalLinkage, Name, - unwrap<Constant>(Aliasee), unwrap(M), PTy->getAddressSpace())); + unwrap<GlobalObject>(Aliasee), unwrap(M), PTy->getAddressSpace())); } /*--.. Operations on functions .............................................--*/ diff --git a/llvm/lib/IR/Globals.cpp b/llvm/lib/IR/Globals.cpp index 8e7478496f0..d4fcf58e98b 100644 --- a/llvm/lib/IR/Globals.cpp +++ b/llvm/lib/IR/Globals.cpp @@ -214,15 +214,11 @@ void GlobalVariable::copyAttributesFrom(const GlobalValue *Src) { //===----------------------------------------------------------------------===// GlobalAlias::GlobalAlias(Type *Ty, LinkageTypes Link, const Twine &Name, - Constant *Aliasee, Module *ParentModule, + GlobalObject *Aliasee, Module *ParentModule, unsigned AddressSpace) : GlobalValue(PointerType::get(Ty, AddressSpace), Value::GlobalAliasVal, &Op<0>(), 1, Link, Name) { LeakDetector::addGarbageObject(this); - - if (Aliasee) - assert(Aliasee->getType() == getType() && - "Alias and aliasee types should match!"); Op<0>() = Aliasee; if (ParentModule) @@ -245,42 +241,4 @@ void GlobalAlias::eraseFromParent() { getParent()->getAliasList().erase(this); } -void GlobalAlias::setAliasee(Constant *Aliasee) { - assert((!Aliasee || Aliasee->getType() == getType()) && - "Alias and aliasee types should match!"); - - setOperand(0, Aliasee); -} - -static GlobalValue *getAliaseeGV(GlobalAlias *GA) { - Constant *C = GA->getAliasee(); - assert(C && "Must alias something"); - - if (GlobalValue *GV = dyn_cast<GlobalValue>(C)) - return GV; - - ConstantExpr *CE = cast<ConstantExpr>(C); - assert((CE->getOpcode() == Instruction::BitCast || - CE->getOpcode() == Instruction::AddrSpaceCast || - CE->getOpcode() == Instruction::GetElementPtr) && - "Unsupported aliasee"); - - return cast<GlobalValue>(CE->getOperand(0)); -} - -GlobalObject *GlobalAlias::getAliasedGlobal() { - SmallPtrSet<GlobalValue*, 3> Visited; - - GlobalAlias *GA = this; - - for (;;) { - GlobalValue *GV = getAliaseeGV(GA); - if (!Visited.insert(GV)) - return nullptr; - - // Iterate over aliasing chain. - GA = dyn_cast<GlobalAlias>(GV); - if (!GA) - return cast<GlobalObject>(GV); - } -} +void GlobalAlias::setAliasee(GlobalObject *Aliasee) { setOperand(0, Aliasee); } diff --git a/llvm/lib/IR/Value.cpp b/llvm/lib/IR/Value.cpp index 9a79e43359e..a3c02862007 100644 --- a/llvm/lib/IR/Value.cpp +++ b/llvm/lib/IR/Value.cpp @@ -301,6 +301,28 @@ void Value::takeName(Value *V) { ST->reinsertValue(this); } +static GlobalObject &findReplacementForAliasUse(Value &C) { + if (auto *GO = dyn_cast<GlobalObject>(&C)) + return *GO; + if (auto *GA = dyn_cast<GlobalAlias>(&C)) + return *GA->getAliasee(); + auto *CE = cast<ConstantExpr>(&C); + assert(CE->getOpcode() == Instruction::BitCast || + CE->getOpcode() == Instruction::GetElementPtr || + CE->getOpcode() == Instruction::AddrSpaceCast); + if (CE->getOpcode() == Instruction::GetElementPtr) + assert(cast<GEPOperator>(CE)->hasAllZeroIndices()); + return findReplacementForAliasUse(*CE->getOperand(0)); +} + +static void replaceAliasUseWith(Use &U, Value *New) { + GlobalObject &Replacement = findReplacementForAliasUse(*New); + auto *Old = &cast<GlobalObject>(*U); + assert(Old != &Replacement && + "replaceAliasUseWith cannot form an alias cycle"); + U.set(&Replacement); +} + #ifndef NDEBUG static bool contains(SmallPtrSet<ConstantExpr *, 4> &Cache, ConstantExpr *Expr, Constant *C) { @@ -351,7 +373,11 @@ void Value::replaceAllUsesWith(Value *New) { Use &U = *UseList; // Must handle Constants specially, we cannot call replaceUsesOfWith on a // constant because they are uniqued. - if (Constant *C = dyn_cast<Constant>(U.getUser())) { + if (auto *C = dyn_cast<Constant>(U.getUser())) { + if (isa<GlobalAlias>(C)) { + replaceAliasUseWith(U, New); + continue; + } if (!isa<GlobalValue>(C)) { C->replaceUsesOfWithOnConstant(this, New, &U); continue; diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp index ff9ca44f870..6ab5e58c4cc 100644 --- a/llvm/lib/IR/Verifier.cpp +++ b/llvm/lib/IR/Verifier.cpp @@ -473,8 +473,6 @@ void Verifier::visitGlobalAlias(const GlobalAlias &GA) { "Alias should have external or external weak linkage!", &GA); Assert1(GA.getAliasee(), "Aliasee cannot be NULL!", &GA); - Assert1(GA.getType() == GA.getAliasee()->getType(), - "Alias and aliasee types should match!", &GA); Assert1(!GA.hasUnnamedAddr(), "Alias cannot have unnamed_addr!", &GA); const Constant *Aliasee = GA.getAliasee(); @@ -506,10 +504,6 @@ void Verifier::visitGlobalAlias(const GlobalAlias &GA) { &GA); } - const GlobalValue *AG = GA.getAliasedGlobal(); - Assert1(AG, "Aliasing chain should end with function or global variable", - &GA); - visitGlobalValue(GA); } |