diff options
author | Anton Korobeynikov <asl@math.spbu.ru> | 2007-04-28 13:45:00 +0000 |
---|---|---|
committer | Anton Korobeynikov <asl@math.spbu.ru> | 2007-04-28 13:45:00 +0000 |
commit | a80e1181b78183dc36ec6568559d38faa86981f0 (patch) | |
tree | 88ca9bd2f28f363e50add28297f6220ac8e09fc1 | |
parent | 44b2c5098f5cf766b4eff43d9eb0d8a9a143e7d8 (diff) | |
download | external_llvm-a80e1181b78183dc36ec6568559d38faa86981f0.zip external_llvm-a80e1181b78183dc36ec6568559d38faa86981f0.tar.gz external_llvm-a80e1181b78183dc36ec6568559d38faa86981f0.tar.bz2 |
Implement review feedback. Aliasees can be either GlobalValue's or
bitcasts of them.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36537 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | docs/BytecodeFormat.html | 14 | ||||
-rw-r--r-- | docs/LangRef.html | 3 | ||||
-rw-r--r-- | include/llvm/Bytecode/BytecodeHandler.h | 6 | ||||
-rw-r--r-- | include/llvm/Function.h | 18 | ||||
-rw-r--r-- | include/llvm/GlobalAlias.h | 37 | ||||
-rw-r--r-- | include/llvm/GlobalValue.h | 10 | ||||
-rw-r--r-- | include/llvm/GlobalVariable.h | 4 | ||||
-rw-r--r-- | lib/AsmParser/llvmAsmParser.y | 80 | ||||
-rw-r--r-- | lib/Bytecode/Reader/Analyzer.cpp | 21 | ||||
-rw-r--r-- | lib/Bytecode/Reader/Reader.cpp | 41 | ||||
-rw-r--r-- | lib/Bytecode/Reader/Reader.h | 9 | ||||
-rw-r--r-- | lib/Bytecode/Writer/SlotCalculator.cpp | 13 | ||||
-rw-r--r-- | lib/Bytecode/Writer/Writer.cpp | 11 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter.cpp | 23 | ||||
-rw-r--r-- | lib/Transforms/IPO/GlobalDCE.cpp | 8 | ||||
-rw-r--r-- | lib/VMCore/AsmWriter.cpp | 14 | ||||
-rw-r--r-- | lib/VMCore/Globals.cpp | 21 | ||||
-rw-r--r-- | lib/VMCore/Module.cpp | 3 | ||||
-rw-r--r-- | lib/VMCore/Verifier.cpp | 4 | ||||
-rw-r--r-- | test/Feature/aliases.ll | 4 |
20 files changed, 231 insertions, 113 deletions
diff --git a/docs/BytecodeFormat.html b/docs/BytecodeFormat.html index 396bf2f..f479ca5 100644 --- a/docs/BytecodeFormat.html +++ b/docs/BytecodeFormat.html @@ -1212,14 +1212,18 @@ the first <a href="#uint32_vbr">uint32_vbr</a> which describes alias itself.</p> linkage, 2 - Weak linkage.</td> </tr> <tr> - <td><a href="#bit">bit(2-31)</a></td> + <td><a href="#bit">bit(2)</a></td> + <td class="td_left">0 - Aliasee is global value. 1 - Aliasee is constant + expression (bitcast of global value)</td> + </tr> + <tr> + <td><a href="#bit">bit(3-31)</a></td> <td class="td_left">Type slot number of type for the alias itself.</td> </tr> </tbody> </table> - <p>The next two <a href="#uint32_vbr">uint32_vbr's</a> describes the - aliasee. </p> + <p>The next <a href="#uint32_vbr">uint32_vbr</a> describes the aliasee. </p> <table> <tbody> @@ -1229,10 +1233,6 @@ the first <a href="#uint32_vbr">uint32_vbr</a> which describes alias itself.</p> </tr> <tr> <td><a href="#uint32_vbr">uint32_vbr</a></td> - <td class="td_left">Type slot number of type for the aliasee.</td> - </tr> - <tr> - <td><a href="#uint32_vbr">uint32_vbr</a></td> <td class="td_left">Slot number of the aliasee.</td> </tr> </tbody> diff --git a/docs/LangRef.html b/docs/LangRef.html index 807d104..54b01ea 100644 --- a/docs/LangRef.html +++ b/docs/LangRef.html @@ -24,6 +24,7 @@ <li><a href="#callingconv">Calling Conventions</a></li> <li><a href="#globalvars">Global Variables</a></li> <li><a href="#functionstructure">Functions</a></li> + <li><a href="aliasstructure">Aliases</a> <li><a href="#paramattrs">Parameter Attributes</a></li> <li><a href="#moduleasm">Module-Level Inline Assembly</a></li> <li><a href="#datalayout">Data Layout</a></li> @@ -705,7 +706,7 @@ a power of 2.</p> </div> <div class="doc_text"> <p>Aliases act as "second name" for the aliasee value (which can be either - function or global variable). Aliases may have an + function or global variable or bitcast of global value). Aliases may have an optional <a href="#linkage">linkage type</a>, and an optional <a href="#visibility">visibility style</a>.</p> diff --git a/include/llvm/Bytecode/BytecodeHandler.h b/include/llvm/Bytecode/BytecodeHandler.h index 3d885e1..e45266b 100644 --- a/include/llvm/Bytecode/BytecodeHandler.h +++ b/include/llvm/Bytecode/BytecodeHandler.h @@ -116,6 +116,12 @@ public: bool isThreadLocal ///< Whether the GV is thread local or not ) {} + virtual void handleGlobalAlias( + const Type* ElemType, + GlobalValue::LinkageTypes Linkage, + unsigned TypeSlotNum, + unsigned AliaseeSlot) { } + /// This method is called when a type list is recognized. It simply /// provides the number of types that the list contains. The handler /// should expect that number of calls to handleType. diff --git a/include/llvm/Function.h b/include/llvm/Function.h index c0984f6..71fb87e 100644 --- a/include/llvm/Function.h +++ b/include/llvm/Function.h @@ -81,6 +81,15 @@ private: void setNext(Function *N) { Next = N; } void setPrev(Function *N) { Prev = N; } + // getNext/Prev - Return the next or previous function in the list. These + // methods should never be used directly, and are only used to implement the + // function list as part of the module. + // + Function *getNext() { return Next; } + const Function *getNext() const { return Next; } + Function *getPrev() { return Prev; } + const Function *getPrev() const { return Prev; } + public: /// Function ctor - If the (optional) Module argument is specified, the /// function is automatically inserted into the end of the function list for @@ -243,15 +252,6 @@ public: Function *Obj = 0; return unsigned(reinterpret_cast<uintptr_t>(&Obj->ArgumentList)); } -private: - // getNext/Prev - Return the next or previous function in the list. These - // methods should never be used directly, and are only used to implement the - // function list as part of the module. - // - Function *getNext() { return Next; } - const Function *getNext() const { return Next; } - Function *getPrev() { return Prev; } - const Function *getPrev() const { return Prev; } }; inline ValueSymbolTable * diff --git a/include/llvm/GlobalAlias.h b/include/llvm/GlobalAlias.h index ec6ea77..04bd5fb 100644 --- a/include/llvm/GlobalAlias.h +++ b/include/llvm/GlobalAlias.h @@ -1,4 +1,4 @@ -//===______-- llvm/GlobalAlias.h - GlobalAlias class ------------*- C++ -*-===// +//===-------- llvm/GlobalAlias.h - GlobalAlias class ------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -8,7 +8,7 @@ //===----------------------------------------------------------------------===// // // This file contains the declaration of the GlobalAlias class, which -// represents a single function or variable alias in the VM. +// represents a single function or variable alias in the IR. // //===----------------------------------------------------------------------===// @@ -36,13 +36,18 @@ class GlobalAlias : public GlobalValue { void setNext(GlobalAlias *N) { Next = N; } void setPrev(GlobalAlias *N) { Prev = N; } - const GlobalValue* Aliasee; - std::string Target; + // getNext/Prev - Return the next or previous alias in the list. + GlobalAlias *getNext() { return Next; } + const GlobalAlias *getNext() const { return Next; } + GlobalAlias *getPrev() { return Prev; } + const GlobalAlias *getPrev() const { return Prev; } + + Use Aliasee; public: /// GlobalAlias ctor - If a parent module is specified, the alias is - /// automatically inserted into the end of the specified modules alias list. + /// automatically inserted into the end of the specified module's alias list. GlobalAlias(const Type *Ty, LinkageTypes Linkage, const std::string &Name = "", - const GlobalValue* Aliasee = 0, Module *Parent = 0); + Constant* Aliasee = 0, Module *Parent = 0); /// isDeclaration - Is this global variable lacking an initializer? If so, /// the global variable is defined in some other translation unit, and is thus @@ -52,30 +57,30 @@ public: /// removeFromParent - This method unlinks 'this' from the containing module, /// but does not delete it. /// - virtual void removeFromParent(); + void removeFromParent(); /// eraseFromParent - This method unlinks 'this' from the containing module /// and deletes it. /// - virtual void eraseFromParent(); + void eraseFromParent(); virtual void print(std::ostream &OS) const; void print(std::ostream *OS) const { if (OS) print(*OS); } - void setAliasee(const GlobalValue* GV); - const GlobalValue* getAliasee() const { return Aliasee; } + /// set/getAliasee - These methods retrive and set alias target. + void setAliasee(Constant* GV); + const Constant* getAliasee() const { + return cast_or_null<Constant>(getOperand(0)); + } + Constant* getAliasee() { + return cast_or_null<Constant>(getOperand(0)); + } // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const GlobalAlias *) { return true; } static inline bool classof(const Value *V) { return V->getValueID() == Value::GlobalAliasVal; } -private: - // getNext/Prev - Return the next or previous alias in the list. - GlobalAlias *getNext() { return Next; } - const GlobalAlias *getNext() const { return Next; } - GlobalAlias *getPrev() { return Prev; } - const GlobalAlias *getPrev() const { return Prev; } }; } // End llvm namespace diff --git a/include/llvm/GlobalValue.h b/include/llvm/GlobalValue.h index 317aa48..014cdbe 100644 --- a/include/llvm/GlobalValue.h +++ b/include/llvm/GlobalValue.h @@ -121,16 +121,6 @@ public: /// value is outside of the current translation unit... virtual bool isDeclaration() const = 0; - /// removeFromParent - This method unlinks 'this' from the containing module, - /// but does not delete it. - /// - virtual void removeFromParent() = 0; - - /// eraseFromParent - This method unlinks 'this' from the containing module - /// and deletes it. - /// - virtual void eraseFromParent() = 0; - /// getParent - Get the module that this global value is contained inside /// of... inline Module *getParent() { return Parent; } diff --git a/include/llvm/GlobalVariable.h b/include/llvm/GlobalVariable.h index 303e57f..00d4acb 100644 --- a/include/llvm/GlobalVariable.h +++ b/include/llvm/GlobalVariable.h @@ -107,12 +107,12 @@ public: /// removeFromParent - This method unlinks 'this' from the containing module, /// but does not delete it. /// - virtual void removeFromParent(); + void removeFromParent(); /// eraseFromParent - This method unlinks 'this' from the containing module /// and deletes it. /// - virtual void eraseFromParent(); + void eraseFromParent(); /// Override Constant's implementation of this method so we can /// replace constant initializers. diff --git a/lib/AsmParser/llvmAsmParser.y b/lib/AsmParser/llvmAsmParser.y index 14524cb..f2b9fb0 100644 --- a/lib/AsmParser/llvmAsmParser.y +++ b/lib/AsmParser/llvmAsmParser.y @@ -480,8 +480,24 @@ static Value *getVal(const Type *Ty, const ValID &ID) { // or an id number that hasn't been read yet. We may be referencing something // forward, so just create an entry to be resolved later and get to it... // - V = new Argument(Ty); - + switch (ID.Type) { + case ValID::GlobalName: + case ValID::GlobalID: + const PointerType *PTy = dyn_cast<PointerType>(Ty); + if (!PTy) { + GenerateError("Invalid type for reference to global" ); + return 0; + } + const Type* ElTy = PTy->getElementType(); + if (const FunctionType *FTy = dyn_cast<FunctionType>(ElTy)) + V = new Function(FTy, GlobalValue::ExternalLinkage); + else + V = new GlobalVariable(ElTy, false, GlobalValue::ExternalLinkage); + break; + default: + V = new Argument(Ty); + } + // Remember where this forward reference came from. FIXME, shouldn't we try // to recycle these things?? CurModule.PlaceHolderInfo.insert(std::make_pair(V, std::make_pair(ID, @@ -987,7 +1003,7 @@ Module *llvm::RunVMAsmParser(const char * AsmString, Module * M) { %type <BasicBlockVal> BasicBlock InstructionList %type <TermInstVal> BBTerminatorInst %type <InstVal> Inst InstVal MemoryInst -%type <ConstVal> ConstVal ConstExpr +%type <ConstVal> ConstVal ConstExpr AliaseeRef %type <ConstVector> ConstVector %type <ArgList> ArgList ArgListH %type <PHIList> PHIList @@ -1943,6 +1959,30 @@ GlobalType : GLOBAL { $$ = false; } | CONSTANT { $$ = true; }; // ThreadLocal ThreadLocal : THREAD_LOCAL { $$ = true; } | { $$ = false; }; +// AliaseeRef - Match either GlobalValue or bitcast to GlobalValue. +AliaseeRef : ResultTypes SymbolicValueRef { + const Type* VTy = $1->get(); + Value *V = getVal(VTy, $2); + GlobalValue* Aliasee = dyn_cast<GlobalValue>(V); + if (!Aliasee) + GEN_ERROR("Aliases can be created only to global values"); + + $$ = Aliasee; + CHECK_FOR_ERROR + delete $1; + } + | BITCAST '(' AliaseeRef TO Types ')' { + Constant *Val = $3; + const Type *DestTy = $5->get(); + if (!CastInst::castIsValid($1, $3, DestTy)) + GEN_ERROR("invalid cast opcode for cast from '" + + Val->getType()->getDescription() + "' to '" + + DestTy->getDescription() + "'"); + + $$ = ConstantExpr::getCast($1, $3, DestTy); + CHECK_FOR_ERROR + delete $5; + }; //===----------------------------------------------------------------------===// // Rules to match Modules @@ -2045,34 +2085,20 @@ Definition CurGV = 0; CHECK_FOR_ERROR } - | OptGlobalAssign GVVisibilityStyle ALIAS AliasLinkage ResultTypes - SymbolicValueRef { + | OptGlobalAssign GVVisibilityStyle ALIAS AliasLinkage AliaseeRef { std::string Name($1); if (Name.empty()) - GEN_ERROR("Alias name cannot be empty") - const PointerType *PFTy = 0; - const FunctionType *Ty = 0; - Value* V = 0; - const Type* VTy = 0; - if (!(PFTy = dyn_cast<PointerType>($5->get())) || - !(Ty = dyn_cast<FunctionType>(PFTy->getElementType()))) { - VTy = $5->get(); - V = getExistingVal(VTy, $6); - } else { - VTy = PFTy; - V = getExistingVal(PFTy, $6); - } - if (V == 0) + GEN_ERROR("Alias name cannot be empty"); + + Constant* Aliasee = $5; + if (Aliasee == 0) GEN_ERROR(std::string("Invalid aliasee for alias: ") + $1); - if (GlobalValue* Aliasee = dyn_cast<GlobalValue>(V)) { - GlobalAlias* GA = new GlobalAlias(VTy, $4, Name, Aliasee, - CurModule.CurrentModule); - GA->setVisibility($2); - InsertValue(GA, CurModule.Values); - } else - GEN_ERROR("Aliases can be created only to global values"); + + GlobalAlias* GA = new GlobalAlias(Aliasee->getType(), $4, Name, Aliasee, + CurModule.CurrentModule); + GA->setVisibility($2); + InsertValue(GA, CurModule.Values); CHECK_FOR_ERROR - delete $5; } | TARGET TargetDefinition { CHECK_FOR_ERROR diff --git a/lib/Bytecode/Reader/Analyzer.cpp b/lib/Bytecode/Reader/Analyzer.cpp index dde73df..2d90c93 100644 --- a/lib/Bytecode/Reader/Analyzer.cpp +++ b/lib/Bytecode/Reader/Analyzer.cpp @@ -179,6 +179,27 @@ public: } + virtual void handleGlobalAlias( + const Type* ElemType, + GlobalValue::LinkageTypes Linkage, + unsigned TypeSlotNum, + unsigned AliaseeSlot) { + if (os) { + *os << " GA: " + << " Linkage=" << Linkage + << " Type="; + //WriteTypeSymbolic(*os, ElemType, M); + *os << " Slot=" << TypeSlotNum << " AliaseeSlot=" << AliaseeSlot + << "\n"; + } + + bca.numValues++; + if (TypeSlotNum > bca.maxValueSlot) + bca.maxValueSlot = TypeSlotNum; + if (AliaseeSlot > bca.maxValueSlot) + bca.maxValueSlot = AliaseeSlot; + } + virtual void handleTypeList(unsigned numEntries) { bca.maxTypeSlot = numEntries - 1; } diff --git a/lib/Bytecode/Reader/Reader.cpp b/lib/Bytecode/Reader/Reader.cpp index f7606c6..99aac05 100644 --- a/lib/Bytecode/Reader/Reader.cpp +++ b/lib/Bytecode/Reader/Reader.cpp @@ -1923,12 +1923,10 @@ void BytecodeReader::ParseModuleGlobalInfo() { // Read aliases... unsigned VarType = read_vbr_uint(); while (VarType != Type::VoidTyID) { // List is terminated by Void - unsigned TypeSlotNo = VarType >> 2; + unsigned TypeSlotNo = VarType >> 3; unsigned EncodedLinkage = VarType & 3; - unsigned AliaseeTypeSlotNo, AliaseeSlotNo; - - AliaseeTypeSlotNo = read_vbr_uint(); - AliaseeSlotNo = read_vbr_uint(); + bool isConstantAliasee = (VarType >> 2) & 1; + unsigned AliaseeSlotNo = read_vbr_uint(); const Type *Ty = getType(TypeSlotNo); if (!Ty) @@ -1937,11 +1935,11 @@ void BytecodeReader::ParseModuleGlobalInfo() { if (!isa<PointerType>(Ty)) error("Alias not a pointer type! Ty= " + Ty->getDescription()); - Value* V = getValue(AliaseeTypeSlotNo, AliaseeSlotNo, false); - if (!V) - error("Invalid aliasee! TypeSlotNo=" + utostr(AliaseeTypeSlotNo) + + Value* V = getValue(TypeSlotNo, AliaseeSlotNo, false); + if (!V && !isConstantAliasee) + error("Invalid aliasee! TypeSlotNo=" + utostr(TypeSlotNo) + " SlotNo=" + utostr(AliaseeSlotNo)); - if (!isa<GlobalValue>(V)) + if (!isConstantAliasee && !isa<GlobalValue>(V)) error("Aliasee is not global value! SlotNo=" + utostr(AliaseeSlotNo)); GlobalValue::LinkageTypes Linkage; @@ -1960,8 +1958,14 @@ void BytecodeReader::ParseModuleGlobalInfo() { } GlobalAlias *GA = new GlobalAlias(Ty, Linkage, "", - dyn_cast<GlobalValue>(V), TheModule); + dyn_cast_or_null<Constant>(V), + TheModule); insertValue(GA, TypeSlotNo, ModuleValues); + if (!V && isConstantAliasee) + Aliasees.push_back(std::make_pair(GA, AliaseeSlotNo)); + + if (Handler) Handler->handleGlobalAlias(Ty, Linkage, + TypeSlotNo, AliaseeSlotNo); VarType = read_vbr_uint(); } } @@ -2068,6 +2072,23 @@ void BytecodeReader::ParseModule() { error("Cannot find initializer value."); } + // And aliasees + while (!Aliasees.empty()) { + GlobalAlias *GA = Aliasees.back().first; + unsigned Slot = Aliasees.back().second; + Aliasees.pop_back(); + + // Look up the aliasee value... + const llvm::PointerType* GAType = GA->getType(); + unsigned TypeSlot = getTypeSlot(GAType); + if (Constant *CV = getConstantValue(TypeSlot, Slot)) { + if (GA->getAliasee()) + error("Aliasee was *already* set?!"); + GA->setAliasee(CV); + } else + error("Cannot find aliasee value."); + } + if (!ConstantFwdRefs.empty()) error("Use of undefined constants in a module"); diff --git a/lib/Bytecode/Reader/Reader.h b/lib/Bytecode/Reader/Reader.h index c852cce..95cf58c 100644 --- a/lib/Bytecode/Reader/Reader.h +++ b/lib/Bytecode/Reader/Reader.h @@ -129,6 +129,9 @@ public: /// them. typedef std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInitsList; + /// @brief A list of global aliases and the slot number for constant aliasees + typedef std::vector<std::pair<GlobalAlias*, unsigned> > AliaseeList; + /// This type maps a typeslot/valueslot pair to the corresponding Value*. /// It is used for dealing with forward references as values are read in. /// @brief A map for dealing with forward references of values. @@ -338,6 +341,12 @@ private: /// of what we must do. GlobalInitsList GlobalInits; + /// Constant values are read in after global aliases. Because of this, we must + /// defer setting the constant aliasees until after module level constants + /// have been read. In the mean time, this list keeps track of what we must + /// do. + AliaseeList Aliasees; + // For lazy reading-in of functions, we need to save away several pieces of // information about each function: its begin and end pointer in the buffer // and its FunctionSlot. diff --git a/lib/Bytecode/Writer/SlotCalculator.cpp b/lib/Bytecode/Writer/SlotCalculator.cpp index 85ccad5..3a038cd 100644 --- a/lib/Bytecode/Writer/SlotCalculator.cpp +++ b/lib/Bytecode/Writer/SlotCalculator.cpp @@ -89,6 +89,12 @@ void SlotCalculator::processModule() { I != E; ++I) CreateSlotIfNeeded(I); + // Add all of the global aliases to the value table... + // + for (Module::const_alias_iterator I = TheModule->alias_begin(), + E = TheModule->alias_end(); I != E; ++I) + CreateSlotIfNeeded(I); + // Add all of the module level constants used as initializers // for (Module::const_global_iterator I = TheModule->global_begin(), @@ -96,6 +102,13 @@ void SlotCalculator::processModule() { if (I->hasInitializer()) CreateSlotIfNeeded(I->getInitializer()); + // Add all of the module level constants used as aliasees + // + for (Module::const_alias_iterator I = TheModule->alias_begin(), + E = TheModule->alias_end(); I != E; ++I) + if (I->getAliasee()) + CreateSlotIfNeeded(I->getAliasee()); + // Now that all global constants have been added, rearrange constant planes // that contain constant strings so that the strings occur at the start of the // plane, not somewhere in the middle. diff --git a/lib/Bytecode/Writer/Writer.cpp b/lib/Bytecode/Writer/Writer.cpp index 7295239..f1c6f6c 100644 --- a/lib/Bytecode/Writer/Writer.cpp +++ b/lib/Bytecode/Writer/Writer.cpp @@ -1095,9 +1095,11 @@ void BytecodeWriter::outputModuleInfoBlock(const Module *M) { // Output aliases for (Module::const_alias_iterator I = M->alias_begin(), E = M->alias_end(); I != E; ++I) { - unsigned Slot = Table.getTypeSlot(I->getType()); - assert(((Slot << 2) >> 2) == Slot && "Slot # too big!"); + unsigned TypeSlotNo = Table.getTypeSlot(I->getType()); + unsigned AliaseeSlotNo = Table.getSlot(I->getAliasee()); + assert(((TypeSlotNo << 3) >> 3) == TypeSlotNo && "Slot # too big!"); unsigned aliasLinkage = 0; + unsigned isConstantAliasee = ((!isa<GlobalValue>(I->getAliasee())) << 2); switch (I->getLinkage()) { case GlobalValue::ExternalLinkage: aliasLinkage = 0; @@ -1111,9 +1113,8 @@ void BytecodeWriter::outputModuleInfoBlock(const Module *M) { default: assert(0 && "Invalid alias linkage"); } - output_vbr((Slot << 2) | aliasLinkage); - output_vbr(Table.getTypeSlot(I->getAliasee()->getType())); - output_vbr(Table.getSlot(I->getAliasee())); + output_vbr((TypeSlotNo << 3) | isConstantAliasee | aliasLinkage); + output_vbr(AliaseeSlotNo); } output_typeid(Table.getTypeSlot(Type::VoidTy)); } diff --git a/lib/CodeGen/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter.cpp index 90a98cb..f757183 100644 --- a/lib/CodeGen/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter.cpp @@ -123,18 +123,29 @@ bool AsmPrinter::doFinalization(Module &M) { } if (TAI->getSetDirective()) { - if (M.alias_size()) + if (!M.alias_empty()) SwitchToTextSection(TAI->getTextSection()); O << "\n"; for (Module::const_alias_iterator I = M.alias_begin(), E = M.alias_end(); I!=E; ++I) { - const GlobalValue *Aliasee = I->getAliasee(); - assert(Aliasee && "Aliasee cannot be null!"); - std::string Target = Mang->getValueName(Aliasee); - std::string Name = Mang->getValueName(I); + const Constant *Aliasee = dyn_cast_or_null<Constant>(I->getAliasee()); + assert(Aliasee && "Aliasee cannot be null"); - // Aliases with external weak linkage was emitted already + std::string Name = Mang->getValueName(I); + std::string Target; + + if (const GlobalValue *GV = dyn_cast<GlobalValue>(Aliasee)) + Target = Mang->getValueName(GV); + else { + const ConstantExpr *CE = 0; + if ((CE = dyn_cast<ConstantExpr>(Aliasee)) && + (CE->getOpcode() == Instruction::BitCast)) + Target = Mang->getValueName(CE->getOperand(0)); + else + assert(0 && "Unsupported aliasee"); + } + if (I->hasExternalLinkage()) O << "\t.globl\t" << Name << "\n"; else if (I->hasWeakLinkage()) diff --git a/lib/Transforms/IPO/GlobalDCE.cpp b/lib/Transforms/IPO/GlobalDCE.cpp index 560bcb5..9015068 100644 --- a/lib/Transforms/IPO/GlobalDCE.cpp +++ b/lib/Transforms/IPO/GlobalDCE.cpp @@ -75,9 +75,8 @@ bool GlobalDCE::runOnModule(Module &M) { for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); I != E; ++I) { - Changed |= RemoveUnusedGlobalValue(*I); // Aliases are always needed even if they are not used. - GlobalIsNeeded(I); + MarkUsedGlobalsAsNeeded(cast<Constant>(I->getAliasee())); } // Now that all globals which are needed are in the AliveGlobals set, we loop @@ -143,10 +142,7 @@ void GlobalDCE::GlobalIsNeeded(GlobalValue *G) { // referenced by the initializer to the alive set. if (GV->hasInitializer()) MarkUsedGlobalsAsNeeded(GV->getInitializer()); - } else if (GlobalAlias *GA = dyn_cast<GlobalAlias>(G)) { - // If this is a global alias we also need it's aliasee - GlobalIsNeeded(const_cast<GlobalValue*>(GA->getAliasee())); - } else { + } else if (!isa<GlobalAlias>(G)) { // Otherwise this must be a function object. We have to scan the body of // the function looking for constants and global values which are used as // operands. Any operands of these types must be processed to ensure that diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index 8834e1e..656a7be 100644 --- a/lib/VMCore/AsmWriter.cpp +++ b/lib/VMCore/AsmWriter.cpp @@ -926,7 +926,7 @@ void AssemblyWriter::printAlias(const GlobalAlias *GA) { assert(0 && "Invalid alias linkage"); } - const GlobalValue *Aliasee = GA->getAliasee(); + const Constant *Aliasee = dyn_cast_or_null<Constant>(GA->getAliasee()); assert(Aliasee && "Aliasee cannot be null"); if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(Aliasee)) { @@ -940,9 +940,15 @@ void AssemblyWriter::printAlias(const GlobalAlias *GA) { Out << getLLVMName(F->getName(), GlobalPrefix); else Out << "@\"\""; - } else - assert(0 && "Unsupported aliasee"); - + } else { + const ConstantExpr *CE = 0; + if ((CE = dyn_cast<ConstantExpr>(Aliasee)) && + (CE->getOpcode() == Instruction::BitCast)) { + writeOperand(CE, false); + } else + assert(0 && "Unsupported aliasee"); + } + printInfoComment(*GA); Out << "\n"; } diff --git a/lib/VMCore/Globals.cpp b/lib/VMCore/Globals.cpp index c64b719..88a8c0b 100644 --- a/lib/VMCore/Globals.cpp +++ b/lib/VMCore/Globals.cpp @@ -163,12 +163,15 @@ void GlobalVariable::replaceUsesOfWithOnConstant(Value *From, Value *To, //===----------------------------------------------------------------------===// GlobalAlias::GlobalAlias(const Type *Ty, LinkageTypes Link, - const std::string &Name, const GlobalValue* aliasee, + const std::string &Name, Constant* aliasee, Module *ParentModule) - : GlobalValue(Ty, Value::GlobalAliasVal, 0, 0, - Link, Name), Aliasee(aliasee) { + : GlobalValue(Ty, Value::GlobalAliasVal, &Aliasee, 1, Link, Name) { LeakDetector::addGarbageObject(this); + if (aliasee) + assert(aliasee->getType() == Ty && "Alias and aliasee types should match!"); + Aliasee.init(aliasee, this); + if (ParentModule) ParentModule->getAliasList().push_back(this); } @@ -190,12 +193,16 @@ void GlobalAlias::eraseFromParent() { } bool GlobalAlias::isDeclaration() const { - return (Aliasee && Aliasee->isDeclaration()); + const GlobalValue* AV = dyn_cast_or_null<const GlobalValue>(getAliasee()); + return (AV && AV->isDeclaration()); } -void GlobalAlias::setAliasee(const GlobalValue *GV) +void GlobalAlias::setAliasee(Constant *Aliasee) { - // FIXME: Some checks? - Aliasee = GV; + if (Aliasee) { + assert(Aliasee->getType() == getType() && + "Alias and aliasee types should match!"); + setOperand(0, Aliasee); + } } diff --git a/lib/VMCore/Module.cpp b/lib/VMCore/Module.cpp index c660323..e20dab3 100644 --- a/lib/VMCore/Module.cpp +++ b/lib/VMCore/Module.cpp @@ -298,6 +298,9 @@ void Module::dropAllReferences() { for(Module::global_iterator I = global_begin(), E = global_end(); I != E; ++I) I->dropAllReferences(); + + for(Module::alias_iterator I = alias_begin(), E = alias_end(); I != E; ++I) + I->dropAllReferences(); } void Module::addLibrary(const std::string& Lib) { diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp index 1578c2d..01eb860 100644 --- a/lib/VMCore/Verifier.cpp +++ b/lib/VMCore/Verifier.cpp @@ -316,7 +316,9 @@ void Verifier::visitGlobalAlias(GlobalAlias &GA) { Assert1(GA.hasExternalLinkage() || GA.hasInternalLinkage() || GA.hasWeakLinkage(), "Alias should have external or external weak linkage!", &GA); - + Assert1(GA.getType() == GA.getAliasee()->getType(), + "Alias and aliasee types should match!", &GA); + visitGlobalValue(GA); } diff --git a/test/Feature/aliases.ll b/test/Feature/aliases.ll index c099cc9..fc5e768 100644 --- a/test/Feature/aliases.ll +++ b/test/Feature/aliases.ll @@ -2,8 +2,6 @@ ; RUN: llvm-as %t1.ll -o - | llvm-dis > %t2.ll ; RUN: diff %t1.ll %t2.ll -; XFAIL: * - @bar = external global i32 @foo1 = alias i32* @bar @foo2 = alias i32* @bar @@ -15,6 +13,8 @@ declare i32 @foo_f() @bar_i = alias internal i32* @bar +@A = alias bitcast (i32* @bar to i64*) + define i32 @test() { entry: %tmp = load i32* @foo1 |