diff options
author | Evan Cheng <evan.cheng@apple.com> | 2009-03-13 07:51:59 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2009-03-13 07:51:59 +0000 |
commit | 1606e8e4cd937e6de6681f686c266cf61722d972 (patch) | |
tree | 0d2dbc91243124186225e830c6b575acc009f33f /lib/CodeGen | |
parent | 79a5cef503c54f07be27c078267df6170cc6390a (diff) | |
download | external_llvm-1606e8e4cd937e6de6681f686c266cf61722d972.tar.gz external_llvm-1606e8e4cd937e6de6681f686c266cf61722d972.tar.bz2 external_llvm-1606e8e4cd937e6de6681f686c266cf61722d972.zip |
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
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 84 | ||||
-rw-r--r-- | lib/CodeGen/MachineFunction.cpp | 27 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 3 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 8 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp | 3 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp | 3 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 6 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp | 2 |
8 files changed, 69 insertions, 67 deletions
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 2a3a8bb32d..b25776abb9 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -240,6 +240,16 @@ void AsmPrinter::SetupMachineFunction(MachineFunction &MF) { IncrementFunctionNumber(); } +namespace { + // SectionCPs - Keep track the alignment, constpool entries per Section. + struct SectionCPs { + const Section *S; + unsigned Alignment; + SmallVector<unsigned, 4> CPEs; + SectionCPs(const Section *s, unsigned a) : S(s), Alignment(a) {}; + }; +} + /// EmitConstantPool - Print to the current output stream assembly /// representations of the constants in the constant pool MCP. This is /// used to print out constants which have been "spilled to memory" by @@ -251,48 +261,60 @@ void AsmPrinter::EmitConstantPool(MachineConstantPool *MCP) { // Calculate sections for constant pool entries. We collect entries to go into // the same section together to reduce amount of section switch statements. - typedef - std::multimap<const Section*, - std::pair<MachineConstantPoolEntry, unsigned> > CPMap; - CPMap CPs; - SmallPtrSet<const Section*, 5> Sections; - + SmallVector<SectionCPs, 4> CPSections; for (unsigned i = 0, e = CP.size(); i != e; ++i) { MachineConstantPoolEntry CPE = CP[i]; + unsigned Align = CPE.getAlignment(); const Section* S = TAI->SelectSectionForMachineConst(CPE.getType()); - CPs.insert(std::make_pair(S, std::make_pair(CPE, i))); - Sections.insert(S); + // The number of sections are small, just do a linear search from the + // last section to the first. + bool Found = false; + unsigned SecIdx = CPSections.size(); + while (SecIdx != 0) { + if (CPSections[--SecIdx].S == S) { + Found = true; + break; + } + } + if (!Found) { + SecIdx = CPSections.size(); + CPSections.push_back(SectionCPs(S, Align)); + } + + if (Align > CPSections[SecIdx].Alignment) + CPSections[SecIdx].Alignment = Align; + CPSections[SecIdx].CPEs.push_back(i); } // Now print stuff into the calculated sections. - for (SmallPtrSet<const Section*, 5>::iterator IS = Sections.begin(), - ES = Sections.end(); IS != ES; ++IS) { - SwitchToSection(*IS); - EmitAlignment(MCP->getConstantPoolAlignment()); + for (unsigned i = 0, e = CPSections.size(); i != e; ++i) { + SwitchToSection(CPSections[i].S); + EmitAlignment(Log2_32(CPSections[i].Alignment)); - std::pair<CPMap::iterator, CPMap::iterator> II = CPs.equal_range(*IS); - for (CPMap::iterator I = II.first, E = II.second; I != E; ++I) { - CPMap::iterator J = next(I); - MachineConstantPoolEntry Entry = I->second.first; - unsigned index = I->second.second; + unsigned Offset = 0; + for (unsigned j = 0, ee = CPSections[i].CPEs.size(); j != ee; ++j) { + unsigned CPI = CPSections[i].CPEs[j]; + MachineConstantPoolEntry CPE = CP[CPI]; + + // Emit inter-object padding for alignment. + unsigned AlignMask = CPE.getAlignment() - 1; + unsigned NewOffset = (Offset + AlignMask) & ~AlignMask; + EmitZeros(NewOffset - Offset); + + const Type *Ty = CPE.getType(); + Offset = NewOffset + TM.getTargetData()->getTypePaddedSize(Ty); O << TAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_' - << index << ":\t\t\t\t\t"; - // O << TAI->getCommentString() << ' ' << - // WriteTypeSymbolic(O, CP[i].first.getType(), 0); + << CPI << ":\t\t\t\t\t"; + if (VerboseAsm) { + O << TAI->getCommentString() << ' '; + WriteTypeSymbolic(O, CPE.getType(), 0); + } O << '\n'; - if (Entry.isMachineConstantPoolEntry()) - EmitMachineConstantPoolValue(Entry.Val.MachineCPVal); + if (CPE.isMachineConstantPoolEntry()) + EmitMachineConstantPoolValue(CPE.Val.MachineCPVal); else - EmitGlobalConstant(Entry.Val.ConstVal); - - // Emit inter-object padding for alignment. - if (J != E) { - const Type *Ty = Entry.getType(); - unsigned EntSize = TM.getTargetData()->getTypePaddedSize(Ty); - unsigned ValEnd = Entry.getOffset() + EntSize; - EmitZeros(J->second.first.getOffset()-ValEnd); - } + EmitGlobalConstant(CPE.Val.ConstVal); } } } diff --git a/lib/CodeGen/MachineFunction.cpp b/lib/CodeGen/MachineFunction.cpp index cf7f39140b..e19cf7a6ed 100644 --- a/lib/CodeGen/MachineFunction.cpp +++ b/lib/CodeGen/MachineFunction.cpp @@ -521,19 +521,12 @@ unsigned MachineConstantPool::getConstantPoolIndex(Constant *C, // Check to see if we already have this constant. // // FIXME, this could be made much more efficient for large constant pools. - unsigned AlignMask = (1 << Alignment)-1; for (unsigned i = 0, e = Constants.size(); i != e; ++i) - if (Constants[i].Val.ConstVal == C && (Constants[i].Offset & AlignMask)== 0) + if (Constants[i].Val.ConstVal == C && + (Constants[i].getAlignment() & (Alignment - 1)) == 0) return i; - unsigned Offset = 0; - if (!Constants.empty()) { - Offset = Constants.back().getOffset(); - Offset += TD->getTypePaddedSize(Constants.back().getType()); - Offset = (Offset+AlignMask)&~AlignMask; - } - - Constants.push_back(MachineConstantPoolEntry(C, Offset)); + Constants.push_back(MachineConstantPoolEntry(C, Alignment)); return Constants.size()-1; } @@ -545,19 +538,11 @@ unsigned MachineConstantPool::getConstantPoolIndex(MachineConstantPoolValue *V, // Check to see if we already have this constant. // // FIXME, this could be made much more efficient for large constant pools. - unsigned AlignMask = (1 << Alignment)-1; int Idx = V->getExistingMachineCPValue(this, Alignment); if (Idx != -1) return (unsigned)Idx; - - unsigned Offset = 0; - if (!Constants.empty()) { - Offset = Constants.back().getOffset(); - Offset += TD->getTypePaddedSize(Constants.back().getType()); - Offset = (Offset+AlignMask)&~AlignMask; - } - - Constants.push_back(MachineConstantPoolEntry(V, Offset)); + + Constants.push_back(MachineConstantPoolEntry(V, Alignment)); return Constants.size()-1; } @@ -568,7 +553,7 @@ void MachineConstantPool::print(raw_ostream &OS) const { Constants[i].Val.MachineCPVal->print(OS); else OS << *(Value*)Constants[i].Val.ConstVal; - OS << " , offset=" << Constants[i].getOffset(); + OS << " , alignment=" << Constants[i].getAlignment(); OS << "\n"; } } diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 671c85e6d7..7cacbd3021 100644 --- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -5672,8 +5672,7 @@ SDValue DAGCombiner::SimplifySelectCC(DebugLoc DL, SDValue N0, SDValue N1, Constant *CA = ConstantArray::get(ArrayType::get(FPTy, 2), Elts, 2); SDValue CPIdx = DAG.getConstantPool(CA, TLI.getPointerTy(), TD.getPrefTypeAlignment(FPTy)); - unsigned Alignment = - 1 << cast<ConstantPoolSDNode>(CPIdx)->getAlignment(); + unsigned Alignment = cast<ConstantPoolSDNode>(CPIdx)->getAlignment(); // Get the offsets to the 0 and 1 element of the array so that we can // select between them. diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 8c074e75eb..fd08ee688d 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -592,7 +592,7 @@ static SDValue ExpandConstantFP(ConstantFPSDNode *CFP, bool UseCP, } SDValue CPIdx = DAG.getConstantPool(LLVMC, TLI.getPointerTy()); - unsigned Alignment = 1 << cast<ConstantPoolSDNode>(CPIdx)->getAlignment(); + unsigned Alignment = cast<ConstantPoolSDNode>(CPIdx)->getAlignment(); if (Extend) return DAG.getExtLoad(ISD::EXTLOAD, dl, OrigVT, DAG.getEntryNode(), @@ -5547,7 +5547,7 @@ SDValue SelectionDAGLegalize::ExpandBUILD_VECTOR(SDNode *Node) { } Constant *CP = ConstantVector::get(CV); SDValue CPIdx = DAG.getConstantPool(CP, TLI.getPointerTy()); - unsigned Alignment = 1 << cast<ConstantPoolSDNode>(CPIdx)->getAlignment(); + unsigned Alignment = cast<ConstantPoolSDNode>(CPIdx)->getAlignment(); return DAG.getLoad(VT, dl, DAG.getEntryNode(), CPIdx, PseudoSourceValue::getConstantPool(), 0, false, Alignment); @@ -6019,7 +6019,7 @@ ExpandIntToFP(bool isSigned, MVT DestTy, SDValue Source, DebugLoc dl) { Constant *FudgeFactor = ConstantInt::get(Type::Int64Ty, FF); SDValue CPIdx = DAG.getConstantPool(FudgeFactor, TLI.getPointerTy()); - unsigned Alignment = 1 << cast<ConstantPoolSDNode>(CPIdx)->getAlignment(); + unsigned Alignment = cast<ConstantPoolSDNode>(CPIdx)->getAlignment(); CPIdx = DAG.getNode(ISD::ADD, dl, TLI.getPointerTy(), CPIdx, CstOffset); Alignment = std::min(Alignment, 4u); SDValue FudgeInReg; @@ -6173,7 +6173,7 @@ SDValue SelectionDAGLegalize::ExpandLegalINT_TO_FP(bool isSigned, Constant *FudgeFactor = ConstantInt::get(Type::Int64Ty, FF); SDValue CPIdx = DAG.getConstantPool(FudgeFactor, TLI.getPointerTy()); - unsigned Alignment = 1 << cast<ConstantPoolSDNode>(CPIdx)->getAlignment(); + unsigned Alignment = cast<ConstantPoolSDNode>(CPIdx)->getAlignment(); CPIdx = DAG.getNode(ISD::ADD, dl, TLI.getPointerTy(), CPIdx, CstOffset); Alignment = std::min(Alignment, 4u); SDValue FudgeInReg; diff --git a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp index 3cc8f966aa..6c70cced15 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp @@ -2289,8 +2289,7 @@ SDValue DAGTypeLegalizer::ExpandIntOp_UINT_TO_FP(SDNode *N) { if (TLI.isBigEndian()) std::swap(Zero, Four); SDValue Offset = DAG.getNode(ISD::SELECT, dl, Zero.getValueType(), SignSet, Zero, Four); - unsigned Alignment = - 1 << cast<ConstantPoolSDNode>(FudgePtr)->getAlignment(); + unsigned Alignment = cast<ConstantPoolSDNode>(FudgePtr)->getAlignment(); FudgePtr = DAG.getNode(ISD::ADD, dl, TLI.getPointerTy(), FudgePtr, Offset); Alignment = std::min(Alignment, 4u); diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp index 852c43089d..5dfd5c3fb2 100644 --- a/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp +++ b/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp @@ -298,11 +298,10 @@ void ScheduleDAGSDNodes::AddOperand(MachineInstr *MI, SDValue Op, const Type *Type = CP->getType(); // MachineConstantPool wants an explicit alignment. if (Align == 0) { - Align = TM.getTargetData()->getPreferredTypeAlignmentShift(Type); + Align = TM.getTargetData()->getPrefTypeAlignment(Type); if (Align == 0) { // Alignment of vector types. FIXME! Align = TM.getTargetData()->getTypePaddedSize(Type); - Align = Log2_64(Align); } } diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 71560fe2ae..b85a04d858 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -1023,8 +1023,7 @@ SDValue SelectionDAG::getConstantPool(Constant *C, MVT VT, unsigned Alignment, int Offset, bool isTarget) { if (Alignment == 0) - Alignment = - TLI.getTargetData()->getPreferredTypeAlignmentShift(C->getType()); + Alignment = TLI.getTargetData()->getPrefTypeAlignment(C->getType()); unsigned Opc = isTarget ? ISD::TargetConstantPool : ISD::ConstantPool; FoldingSetNodeID ID; AddNodeIDNode(ID, Opc, getVTList(VT), 0, 0); @@ -1046,8 +1045,7 @@ SDValue SelectionDAG::getConstantPool(MachineConstantPoolValue *C, MVT VT, unsigned Alignment, int Offset, bool isTarget) { if (Alignment == 0) - Alignment = - TLI.getTargetData()->getPreferredTypeAlignmentShift(C->getType()); + Alignment = TLI.getTargetData()->getPrefTypeAlignment(C->getType()); unsigned Opc = isTarget ? ISD::TargetConstantPool : ISD::ConstantPool; FoldingSetNodeID ID; AddNodeIDNode(ID, Opc, getVTList(VT), 0, 0); diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp index 0392338762..3eec684c6f 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp @@ -162,7 +162,7 @@ std::string DOTGraphTraits<SelectionDAG*>::getNodeLabel(const SDNode *Node, Op += '>'; } } - Op += " A=" + itostr(1 << CP->getAlignment()); + Op += " A=" + itostr(CP->getAlignment()); } else if (const BasicBlockSDNode *BBDN = dyn_cast<BasicBlockSDNode>(Node)) { Op = "BB: "; const Value *LBB = (const Value*)BBDN->getBasicBlock()->getBasicBlock(); |