From 83f6120c9a1fe758b2502b060cd7ae9a981ecc39 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 28 Oct 2009 01:12:16 +0000 Subject: [PATCH] Allow constants of different types to share constant pool entries if they have compatible encodings. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@85359 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/MachineFunction.cpp | 50 +++++++++++++++++++++-- test/CodeGen/X86/constant-pool-sharing.ll | 19 +++++++++ 2 files changed, 66 insertions(+), 3 deletions(-) create mode 100644 test/CodeGen/X86/constant-pool-sharing.ll diff --git a/lib/CodeGen/MachineFunction.cpp b/lib/CodeGen/MachineFunction.cpp index 3bd33dccf71..eeb7f215663 100644 --- a/lib/CodeGen/MachineFunction.cpp +++ b/lib/CodeGen/MachineFunction.cpp @@ -581,6 +581,47 @@ MachineConstantPool::~MachineConstantPool() { delete Constants[i].Val.MachineCPVal; } +/// CanShareConstantPoolEntry - Test whether the given two constants +/// can be allocated the same constant pool entry. +static bool CanShareConstantPoolEntry(Constant *A, Constant *B, + const TargetData *TD) { + // Handle the trivial case quickly. + if (A == B) return true; + + // If they have the same type but weren't the same constant, quickly + // reject them. + if (A->getType() == B->getType()) return false; + + // For now, only support constants with the same size. + if (TD->getTypeStoreSize(A->getType()) != TD->getTypeStoreSize(B->getType())) + return false; + + // If a floating-point value and an integer value have the same encoding, + // they can share a constant-pool entry. + if (ConstantFP *AFP = dyn_cast(A)) + if (ConstantInt *BI = dyn_cast(B)) + return AFP->getValueAPF().bitcastToAPInt() == BI->getValue(); + if (ConstantFP *BFP = dyn_cast(B)) + if (ConstantInt *AI = dyn_cast(A)) + return BFP->getValueAPF().bitcastToAPInt() == AI->getValue(); + + // Two vectors can share an entry if each pair of corresponding + // elements could. + if (ConstantVector *AV = dyn_cast(A)) + if (ConstantVector *BV = dyn_cast(B)) { + if (AV->getType()->getNumElements() != BV->getType()->getNumElements()) + return false; + for (unsigned i = 0, e = AV->getType()->getNumElements(); i != e; ++i) + if (!CanShareConstantPoolEntry(AV->getOperand(i), BV->getOperand(i), TD)) + return false; + return true; + } + + // TODO: Handle other cases. + + return false; +} + /// getConstantPoolIndex - Create a new entry in the constant pool or return /// an existing one. User must specify the log2 of the minimum required /// alignment for the object. @@ -589,14 +630,17 @@ unsigned MachineConstantPool::getConstantPoolIndex(Constant *C, unsigned Alignment) { assert(Alignment && "Alignment must be specified!"); if (Alignment > PoolAlignment) PoolAlignment = Alignment; - + // Check to see if we already have this constant. // // FIXME, this could be made much more efficient for large constant pools. for (unsigned i = 0, e = Constants.size(); i != e; ++i) - if (Constants[i].Val.ConstVal == C && - (Constants[i].getAlignment() & (Alignment - 1)) == 0) + if (!Constants[i].isMachineConstantPoolEntry() && + CanShareConstantPoolEntry(Constants[i].Val.ConstVal, C, TD)) { + if ((unsigned)Constants[i].getAlignment() < Alignment) + Constants[i].Alignment = Alignment; return i; + } Constants.push_back(MachineConstantPoolEntry(C, Alignment)); return Constants.size()-1; diff --git a/test/CodeGen/X86/constant-pool-sharing.ll b/test/CodeGen/X86/constant-pool-sharing.ll new file mode 100644 index 00000000000..c3e97adffb1 --- /dev/null +++ b/test/CodeGen/X86/constant-pool-sharing.ll @@ -0,0 +1,19 @@ +; RUN: llc < %s -march=x86-64 | FileCheck %s + +; llc should share constant pool entries between this integer vector +; and this floating-point vector since they have the same encoding. + +; CHECK: LCPI1_0(%rip), %xmm0 +; CHECK: movaps %xmm0, (%rdi) +; CHECK: movaps %xmm0, (%rsi) + +define void @foo(<4 x i32>* %p, <4 x float>* %q, i1 %t) nounwind { +entry: + br label %loop +loop: + store <4 x i32>, <4 x i32>* %p + store <4 x float>, <4 x float>* %q + br i1 %t, label %loop, label %ret +ret: + ret void +}