summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/X86/X86TargetObjectFile.cpp
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2014-07-14 22:57:27 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2014-07-14 22:57:27 +0000
commit8bce66b09392b03ef73e0db8419dfd42aaf73c82 (patch)
tree2b9e0581fb34175f3e7862c3a4f9b2b505eb70d1 /llvm/lib/Target/X86/X86TargetObjectFile.cpp
parent2034ac81816d6de20b9e0253a6a2a09414571e0e (diff)
downloadbcm5719-llvm-8bce66b09392b03ef73e0db8419dfd42aaf73c82.tar.gz
bcm5719-llvm-8bce66b09392b03ef73e0db8419dfd42aaf73c82.zip
CodeGen: Stick constant pool entries in COMDAT sections for WinCOFF
COFF lacks a feature that other object file formats support: mergeable sections. To work around this, MSVC sticks constant pool entries in special COMDAT sections so that each constant is in it's own section. This permits unused constants to be dropped and it also allows duplicate constants in different translation units to get merged together. This fixes PR20262. Differential Revision: http://reviews.llvm.org/D4482 llvm-svn: 213006
Diffstat (limited to 'llvm/lib/Target/X86/X86TargetObjectFile.cpp')
-rw-r--r--llvm/lib/Target/X86/X86TargetObjectFile.cpp61
1 files changed, 61 insertions, 0 deletions
diff --git a/llvm/lib/Target/X86/X86TargetObjectFile.cpp b/llvm/lib/Target/X86/X86TargetObjectFile.cpp
index 8157085feae..c7802320b06 100644
--- a/llvm/lib/Target/X86/X86TargetObjectFile.cpp
+++ b/llvm/lib/Target/X86/X86TargetObjectFile.cpp
@@ -8,10 +8,12 @@
//===----------------------------------------------------------------------===//
#include "X86TargetObjectFile.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/IR/Mangler.h"
#include "llvm/IR/Operator.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
+#include "llvm/MC/MCSectionCOFF.h"
#include "llvm/MC/MCSectionELF.h"
#include "llvm/Support/Dwarf.h"
#include "llvm/Target/TargetLowering.h"
@@ -106,3 +108,62 @@ const MCExpr *X86WindowsTargetObjectFile::getExecutableRelativeSymbol(
MCSymbolRefExpr::VK_COFF_IMGREL32,
getContext());
}
+
+static std::string APIntToHexString(const APInt &AI, unsigned Width) {
+ std::string HexString = utohexstr(AI.getLimitedValue(), /*LowerCase=*/true);
+ unsigned Size = HexString.size();
+ assert(Width >= Size && "hex string is too large!");
+ HexString.insert(HexString.begin(), Width - Size, '0');
+
+ return HexString;
+}
+
+
+static std::string scalarConstantToHexString(const Constant *C) {
+ Type *Ty = C->getType();
+ if (Ty->isFloatTy()) {
+ const auto *CFP = cast<ConstantFP>(C);
+ return APIntToHexString(CFP->getValueAPF().bitcastToAPInt(), /*Width=*/8);
+ } else if (Ty->isDoubleTy()) {
+ const auto *CFP = cast<ConstantFP>(C);
+ return APIntToHexString(CFP->getValueAPF().bitcastToAPInt(), /*Width=*/16);
+ } else if (const auto *ITy = dyn_cast<IntegerType>(Ty)) {
+ const auto *CI = cast<ConstantInt>(C);
+ return APIntToHexString(CI->getValue(), (ITy->getBitWidth() / 8) * 2);
+ }
+ llvm_unreachable("unexpected constant pool element type!");
+}
+
+const MCSection *
+X86WindowsTargetObjectFile::getSectionForConstant(SectionKind Kind,
+ const Constant *C) const {
+ if (Kind.isReadOnly()) {
+ if (C) {
+ Type *Ty = C->getType();
+ SmallString<32> COMDATSymName;
+ if (Ty->isFloatTy() || Ty->isDoubleTy()) {
+ COMDATSymName = "__real@";
+ COMDATSymName += scalarConstantToHexString(C);
+ } else if (const auto *VTy = dyn_cast<VectorType>(Ty)) {
+ uint64_t NumBits = VTy->getBitWidth();
+ if (NumBits == 128 || NumBits == 256) {
+ const auto *CDV = cast<ConstantDataVector>(C);
+ COMDATSymName = NumBits == 128 ? "__xmm@" : "__ymm@";
+ for (int I = CDV->getNumElements() - 1, E = -1; I != E; --I)
+ COMDATSymName +=
+ scalarConstantToHexString(CDV->getElementAsConstant(I));
+ }
+ }
+ if (!COMDATSymName.empty()) {
+ unsigned Characteristics = COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
+ COFF::IMAGE_SCN_MEM_READ |
+ COFF::IMAGE_SCN_LNK_COMDAT;
+ return getContext().getCOFFSection(".rdata", Characteristics, Kind,
+ COMDATSymName,
+ COFF::IMAGE_COMDAT_SELECT_ANY);
+ }
+ }
+ }
+
+ return TargetLoweringObjectFile::getSectionForConstant(Kind, C);
+}
OpenPOWER on IntegriCloud