summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Target/ARM/ARMAsmPrinter.cpp11
-rw-r--r--llvm/lib/Target/ARM/ARMConstantPoolValue.cpp17
-rw-r--r--llvm/lib/Target/ARM/ARMConstantPoolValue.h12
-rw-r--r--llvm/test/CodeGen/ARM/constantpool-promote-duplicate.ll21
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)
OpenPOWER on IntegriCloud