diff options
author | Evan Cheng <evan.cheng@apple.com> | 2008-08-08 06:56:16 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2008-08-08 06:56:16 +0000 |
commit | 655fa0fec4b9252f4d260f8ff46982e8c43fe8ac (patch) | |
tree | 1bc5a80a02557ef500263a0a57c1bbe4206829ba /llvm/lib/Target/ARM/ARMAsmPrinter.cpp | |
parent | 319548b93c19fc504c17bf507f229faab38c384e (diff) | |
download | bcm5719-llvm-655fa0fec4b9252f4d260f8ff46982e8c43fe8ac.tar.gz bcm5719-llvm-655fa0fec4b9252f4d260f8ff46982e8c43fe8ac.zip |
It's not legal to output a GV in a coalesced section if it's used in an ARM PIC relative constantpool.
llvm-svn: 54519
Diffstat (limited to 'llvm/lib/Target/ARM/ARMAsmPrinter.cpp')
-rw-r--r-- | llvm/lib/Target/ARM/ARMAsmPrinter.cpp | 32 |
1 files changed, 23 insertions, 9 deletions
diff --git a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp index 3b30f9c5a0d..420ccd0bcc9 100644 --- a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp +++ b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp @@ -29,6 +29,7 @@ #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" +#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Support/Compiler.h" @@ -65,14 +66,18 @@ namespace { typedef std::map<const Value *, unsigned> ValueMapTy; ValueMapTy NumberForBB; - /// Keeps the set of GlobalValues that require non-lazy-pointers for - /// indirect access. + /// GVNonLazyPtrs - Keeps the set of GlobalValues that require + /// non-lazy-pointers for indirect access. std::set<std::string> GVNonLazyPtrs; - /// Keeps the set of external function GlobalAddresses that the asm - /// printer should generate stubs for. + /// FnStubs - Keeps the set of external function GlobalAddresses that the + /// asm printer should generate stubs for. std::set<std::string> FnStubs; + /// PCRelGVs - Keeps the set of GlobalValues used in pc relative + /// constantpool. + SmallPtrSet<const GlobalValue*, 8> PCRelGVs; + /// True if asm printer is printing a series of CONSTPOOL_ENTRY. bool InCPMode; @@ -124,10 +129,12 @@ namespace { /// specified function body into. virtual std::string getSectionForFunction(const Function &F) const; + /// EmitMachineConstantPoolValue - Print a machine constantpool value to + /// the .s file. virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) { printDataDirective(MCPV->getType()); - ARMConstantPoolValue *ACPV = (ARMConstantPoolValue*)MCPV; + ARMConstantPoolValue *ACPV = static_cast<ARMConstantPoolValue*>(MCPV); GlobalValue *GV = ACPV->getGV(); std::string Name = GV ? Mang->getValueName(GV) : TAI->getGlobalPrefix(); if (!GV) @@ -680,9 +687,15 @@ void ARMAsmPrinter::printCPInstOperand(const MachineInstr *MI, int OpNo, const MachineConstantPoolEntry &MCPE = // Chasing pointers is fun? MI->getParent()->getParent()->getConstantPool()->getConstants()[CPI]; - if (MCPE.isMachineConstantPoolEntry()) + if (MCPE.isMachineConstantPoolEntry()) { EmitMachineConstantPoolValue(MCPE.Val.MachineCPVal); - else { + ARMConstantPoolValue *ACPV = + static_cast<ARMConstantPoolValue*>(MCPE.Val.MachineCPVal); + if (ACPV->getPCAdjustment() != 0) { + const GlobalValue *GV = ACPV->getGV(); + PCRelGVs.insert(GV); + } + } else { EmitGlobalConstant(MCPE.Val.ConstVal); // remember to emit the weak reference if (const GlobalValue *GV = dyn_cast<GlobalValue>(MCPE.Val.ConstVal)) @@ -850,7 +863,8 @@ void ARMAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) { return; } - std::string SectionName = TAI->SectionForGlobal(GVar); + bool NoCoalesc = PCRelGVs.count(GVar); + std::string SectionName = TAI->SectionForGlobal(GVar, NoCoalesc); std::string name = Mang->getValueName(GVar); Constant *C = GVar->getInitializer(); const Type *Type = C->getType(); @@ -887,7 +901,7 @@ void ARMAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) { if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. if (TAI->getLCOMMDirective() != NULL) { - if (GVar->hasInternalLinkage()) { + if (NoCoalesc || GVar->hasInternalLinkage()) { O << TAI->getLCOMMDirective() << name << "," << Size; if (Subtarget->isTargetDarwin()) O << "," << Align; |