diff options
-rw-r--r-- | llvm/lib/Target/ARM/ARMAsmPrinter.cpp | 11 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMConstantPoolValue.cpp | 17 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMConstantPoolValue.h | 12 | ||||
-rw-r--r-- | llvm/test/CodeGen/ARM/constantpool-promote-duplicate.ll | 21 |
4 files changed, 48 insertions, 13 deletions
diff --git a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp index 8e425ddcdad..13335a84f6d 100644 --- a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp +++ b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp @@ -865,11 +865,12 @@ EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) { // However, if this global is promoted into several functions we must ensure // we don't try and emit duplicate symbols! auto *ACPC = cast<ARMConstantPoolConstant>(ACPV); - auto *GV = ACPC->getPromotedGlobal(); - if (!EmittedPromotedGlobalLabels.count(GV)) { - MCSymbol *GVSym = getSymbol(GV); - OutStreamer->EmitLabel(GVSym); - EmittedPromotedGlobalLabels.insert(GV); + for (const auto *GV : ACPC->promotedGlobals()) { + if (!EmittedPromotedGlobalLabels.count(GV)) { + MCSymbol *GVSym = getSymbol(GV); + OutStreamer->EmitLabel(GVSym); + EmittedPromotedGlobalLabels.insert(GV); + } } return EmitGlobalConstant(DL, ACPC->getPromotedGlobalInit()); } diff --git a/llvm/lib/Target/ARM/ARMConstantPoolValue.cpp b/llvm/lib/Target/ARM/ARMConstantPoolValue.cpp index 9705c8b718b..88b3683bd75 100644 --- a/llvm/lib/Target/ARM/ARMConstantPoolValue.cpp +++ b/llvm/lib/Target/ARM/ARMConstantPoolValue.cpp @@ -140,8 +140,9 @@ ARMConstantPoolConstant::ARMConstantPoolConstant(const Constant *C, ARMConstantPoolConstant::ARMConstantPoolConstant(const GlobalVariable *GV, const Constant *C) : ARMConstantPoolValue((Type *)C->getType(), 0, ARMCP::CPPromotedGlobal, 0, - ARMCP::no_modifier, false), - CVal(C), GVar(GV) {} + ARMCP::no_modifier, false), CVal(C) { + GVars.insert(GV); +} ARMConstantPoolConstant * ARMConstantPoolConstant::Create(const Constant *C, unsigned ID) { @@ -189,7 +190,15 @@ const BlockAddress *ARMConstantPoolConstant::getBlockAddress() const { int ARMConstantPoolConstant::getExistingMachineCPValue(MachineConstantPool *CP, unsigned Alignment) { - return getExistingMachineCPValueImpl<ARMConstantPoolConstant>(CP, Alignment); + int index = + getExistingMachineCPValueImpl<ARMConstantPoolConstant>(CP, Alignment); + if (index != -1) { + auto *CPV = static_cast<ARMConstantPoolValue*>( + CP->getConstants()[index].Val.MachineCPVal); + auto *Constant = cast<ARMConstantPoolConstant>(CPV); + Constant->GVars.insert(GVars.begin(), GVars.end()); + } + return index; } bool ARMConstantPoolConstant::hasSameValue(ARMConstantPoolValue *ACPV) { @@ -199,6 +208,8 @@ bool ARMConstantPoolConstant::hasSameValue(ARMConstantPoolValue *ACPV) { void ARMConstantPoolConstant::addSelectionDAGCSEId(FoldingSetNodeID &ID) { ID.AddPointer(CVal); + for (const auto *GV : GVars) + ID.AddPointer(GV); ARMConstantPoolValue::addSelectionDAGCSEId(ID); } diff --git a/llvm/lib/Target/ARM/ARMConstantPoolValue.h b/llvm/lib/Target/ARM/ARMConstantPoolValue.h index 61c521581f7..30ce8716c5c 100644 --- a/llvm/lib/Target/ARM/ARMConstantPoolValue.h +++ b/llvm/lib/Target/ARM/ARMConstantPoolValue.h @@ -15,6 +15,7 @@ #define LLVM_LIB_TARGET_ARM_ARMCONSTANTPOOLVALUE_H #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/SmallPtrSet.h" #include "llvm/CodeGen/MachineConstantPool.h" #include "llvm/Support/Casting.h" #include <string> @@ -80,8 +81,8 @@ protected: for (unsigned i = 0, e = Constants.size(); i != e; ++i) { if (Constants[i].isMachineConstantPoolEntry() && (Constants[i].getAlignment() & AlignMask) == 0) { - ARMConstantPoolValue *CPV = - (ARMConstantPoolValue *)Constants[i].Val.MachineCPVal; + auto *CPV = + static_cast<ARMConstantPoolValue*>(Constants[i].Val.MachineCPVal); if (Derived *APC = dyn_cast<Derived>(CPV)) if (cast<Derived>(this)->equals(APC)) return i; @@ -139,7 +140,7 @@ inline raw_ostream &operator<<(raw_ostream &O, const ARMConstantPoolValue &V) { /// Functions, and BlockAddresses. class ARMConstantPoolConstant : public ARMConstantPoolValue { const Constant *CVal; // Constant being loaded. - const GlobalVariable *GVar = nullptr; + SmallPtrSet<const GlobalVariable*, 1> GVars; ARMConstantPoolConstant(const Constant *C, unsigned ID, @@ -173,8 +174,9 @@ public: const GlobalValue *getGV() const; const BlockAddress *getBlockAddress() const; - const GlobalVariable *getPromotedGlobal() const { - return dyn_cast_or_null<GlobalVariable>(GVar); + typedef SmallPtrSet<const GlobalVariable *, 1>::iterator promoted_iterator; + iterator_range<promoted_iterator> promotedGlobals() { + return iterator_range<promoted_iterator>(GVars.begin(), GVars.end()); } const Constant *getPromotedGlobalInit() const { diff --git a/llvm/test/CodeGen/ARM/constantpool-promote-duplicate.ll b/llvm/test/CodeGen/ARM/constantpool-promote-duplicate.ll new file mode 100644 index 00000000000..70c4807a044 --- /dev/null +++ b/llvm/test/CodeGen/ARM/constantpool-promote-duplicate.ll @@ -0,0 +1,21 @@ +; RUN: llc -mtriple=arm-eabi -relocation-model=static -arm-promote-constant < %s | FileCheck %s + +@const1 = private unnamed_addr constant i32 0, align 4 +@const2 = private unnamed_addr constant i32 0, align 4 + +; const1 and const2 both need labels for debug info, but will be coalesced into +; a single constpool entry + +; CHECK-LABEL: @test1 +; CHECK-DAG: const1: +; CHECK-DAG: const2: +; CHECK: .fnend +define void @test1() { + %1 = load i32, i32* @const1, align 4 + call void @a(i32 %1) + %2 = load i32, i32* @const2, align 4 + call void @a(i32 %2) + ret void +} + +declare void @a(i32) |