From 1606e8e4cd937e6de6681f686c266cf61722d972 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Fri, 13 Mar 2009 07:51:59 +0000 Subject: Fix some significant problems with constant pools that resulted in unnecessary paddings between constant pool entries, larger than necessary alignments (e.g. 8 byte alignment for .literal4 sections), and potentially other issues. 1. ConstantPoolSDNode alignment field is log2 value of the alignment requirement. This is not consistent with other SDNode variants. 2. MachineConstantPool alignment field is also a log2 value. 3. However, some places are creating ConstantPoolSDNode with alignment value rather than log2 values. This creates entries with artificially large alignments, e.g. 256 for SSE vector values. 4. Constant pool entry offsets are computed when they are created. However, asm printer group them by sections. That means the offsets are no longer valid. However, asm printer uses them to determine size of padding between entries. 5. Asm printer uses expensive data structure multimap to track constant pool entries by sections. 6. Asm printer iterate over SmallPtrSet when it's emitting constant pool entries. This is non-deterministic. Solutions: 1. ConstantPoolSDNode alignment field is changed to keep non-log2 value. 2. MachineConstantPool alignment field is also changed to keep non-log2 value. 3. Functions that create ConstantPool nodes are passing in non-log2 alignments. 4. MachineConstantPoolEntry no longer keeps an offset field. It's replaced with an alignment field. Offsets are not computed when constant pool entries are created. They are computed on the fly in asm printer and JIT. 5. Asm printer uses cheaper data structure to group constant pool entries. 6. Asm printer compute entry offsets after grouping is done. 7. Change JIT code to compute entry offsets on the fly. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@66875 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/ExecutionEngine/JIT/JITEmitter.cpp | 58 ++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 23 deletions(-) (limited to 'lib/ExecutionEngine') diff --git a/lib/ExecutionEngine/JIT/JITEmitter.cpp b/lib/ExecutionEngine/JIT/JITEmitter.cpp index 0273bc1..54c5451 100644 --- a/lib/ExecutionEngine/JIT/JITEmitter.cpp +++ b/lib/ExecutionEngine/JIT/JITEmitter.cpp @@ -98,7 +98,7 @@ namespace { /// external functions. std::map ExternalFnToStubMap; - //map addresses to indexes in the GOT + /// revGOTMap - map addresses to indexes in the GOT std::map revGOTMap; unsigned nextGOTIndex; @@ -562,6 +562,10 @@ namespace { /// void *ConstantPoolBase; + /// ConstPoolAddresses - Addresses of individual constant pool entries. + /// + SmallVector ConstPoolAddresses; + /// JumpTable - The jump tables for the current function. /// MachineJumpTableInfo *JumpTable; @@ -787,15 +791,19 @@ void JITEmitter::AddStubToCurrentFunction(void *StubAddr) { FnRefs.insert(CurFn); } -static unsigned GetConstantPoolSizeInBytes(MachineConstantPool *MCP) { +static unsigned GetConstantPoolSizeInBytes(MachineConstantPool *MCP, + const TargetData *TD) { const std::vector &Constants = MCP->getConstants(); if (Constants.empty()) return 0; - MachineConstantPoolEntry CPE = Constants.back(); - unsigned Size = CPE.Offset; - const Type *Ty = CPE.isMachineConstantPoolEntry() - ? CPE.Val.MachineCPVal->getType() : CPE.Val.ConstVal->getType(); - Size += TheJIT->getTargetData()->getTypePaddedSize(Ty); + unsigned Size = 0; + for (unsigned i = 0, e = Constants.size(); i != e; ++i) { + MachineConstantPoolEntry CPE = Constants[i]; + unsigned AlignMask = CPE.getAlignment() - 1; + Size = (Size + AlignMask) & ~AlignMask; + const Type *Ty = CPE.getType(); + Size += TD->getTypePaddedSize(Ty); + } return Size; } @@ -979,11 +987,10 @@ void JITEmitter::startFunction(MachineFunction &F) { ActualSize = RoundUpToAlign(ActualSize, 16); // Add the alignment of the constant pool - ActualSize = RoundUpToAlign(ActualSize, - 1 << MCP->getConstantPoolAlignment()); + ActualSize = RoundUpToAlign(ActualSize, MCP->getConstantPoolAlignment()); // Add the constant pool size - ActualSize += GetConstantPoolSizeInBytes(MCP); + ActualSize += GetConstantPoolSizeInBytes(MCP, TheJIT->getTargetData()); // Add the aligment of the jump table info ActualSize = RoundUpToAlign(ActualSize, MJTI->getAlignment()); @@ -1139,6 +1146,7 @@ bool JITEmitter::finishFunction(MachineFunction &F) { << ": " << (FnEnd-FnStart) << " bytes of text, " << Relocations.size() << " relocations\n"; Relocations.clear(); + ConstPoolAddresses.clear(); // Mark code region readable and executable if it's not so already. MemMgr->setMemoryExecutable(); @@ -1274,13 +1282,8 @@ void JITEmitter::emitConstantPool(MachineConstantPool *MCP) { const std::vector &Constants = MCP->getConstants(); if (Constants.empty()) return; - MachineConstantPoolEntry CPE = Constants.back(); - unsigned Size = CPE.Offset; - const Type *Ty = CPE.isMachineConstantPoolEntry() - ? CPE.Val.MachineCPVal->getType() : CPE.Val.ConstVal->getType(); - Size += TheJIT->getTargetData()->getTypePaddedSize(Ty); - - unsigned Align = 1 << MCP->getConstantPoolAlignment(); + unsigned Size = GetConstantPoolSizeInBytes(MCP, TheJIT->getTargetData()); + unsigned Align = MCP->getConstantPoolAlignment(); ConstantPoolBase = allocateSpace(Size, Align); ConstantPool = MCP; @@ -1290,16 +1293,26 @@ void JITEmitter::emitConstantPool(MachineConstantPool *MCP) { << "] (size: " << Size << ", alignment: " << Align << ")\n"; // Initialize the memory for all of the constant pool entries. + unsigned Offset = 0; for (unsigned i = 0, e = Constants.size(); i != e; ++i) { - void *CAddr = (char*)ConstantPoolBase+Constants[i].Offset; - if (Constants[i].isMachineConstantPoolEntry()) { + MachineConstantPoolEntry CPE = Constants[i]; + unsigned AlignMask = CPE.getAlignment() - 1; + Offset = (Offset + AlignMask) & ~AlignMask; + + uintptr_t CAddr = (uintptr_t)ConstantPoolBase + Offset; + ConstPoolAddresses.push_back(CAddr); + if (CPE.isMachineConstantPoolEntry()) { // FIXME: add support to lower machine constant pool values into bytes! cerr << "Initialize memory with machine specific constant pool entry" << " has not been implemented!\n"; abort(); } - TheJIT->InitializeMemory(Constants[i].Val.ConstVal, CAddr); - DOUT << "JIT: CP" << i << " at [" << CAddr << "]\n"; + TheJIT->InitializeMemory(CPE.Val.ConstVal, (void*)CAddr); + DOUT << "JIT: CP" << i << " at [0x" + << std::hex << CAddr << std::dec << "]\n"; + + const Type *Ty = CPE.Val.ConstVal->getType(); + Offset += TheJIT->getTargetData()->getTypePaddedSize(Ty); } } @@ -1398,8 +1411,7 @@ void *JITEmitter::finishGVStub(const GlobalValue* GV) { uintptr_t JITEmitter::getConstantPoolEntryAddress(unsigned ConstantNum) const { assert(ConstantNum < ConstantPool->getConstants().size() && "Invalid ConstantPoolIndex!"); - return (uintptr_t)ConstantPoolBase + - ConstantPool->getConstants()[ConstantNum].Offset; + return ConstPoolAddresses[ConstantNum]; } // getJumpTableEntryAddress - Return the address of the JumpTable with index -- cgit v1.1