llvm.org GIT mirror llvm / f1d015f
Use ArrayRecycler for MachineInstr operand lists. Instead of an std::vector<MachineOperand>, use MachineOperand arrays from an ArrayRecycler living in MachineFunction. This has several advantages: - MachineInstr now has a trivial destructor, making it possible to delete them in batches when destroying MachineFunction. This will be enabled in a later patch. - Bypassing malloc() and free() can be faster, depending on the system library. - MachineInstr objects and their operands are allocated from the same BumpPtrAllocator, so they will usually be next to each other in memory, providing better locality of reference. - Reduce MachineInstr footprint. A std::vector is 24 bytes, the new operand array representation only uses 8+4+1 bytes in MachineInstr. - Better control over operand array reallocations. In the old representation, the use-def chains would be reordered whenever a std::vector reached its capacity. The new implementation never changes the use-def chain order. Note that some decisions in the code generator depend on the use-def chain orders, so this patch may cause different assembly to be produced in a few cases. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@171598 91177308-0d34-0410-b5e6-96231b3b80d8 Jakob Stoklund Olesen 7 years ago
5 changed file(s) with 141 addition(s) and 87 deletion(s). Raw diff Collapse all Expand all
2020 #include "llvm/ADT/ilist.h"
2121 #include "llvm/CodeGen/MachineBasicBlock.h"
2222 #include "llvm/Support/Allocator.h"
23 #include "llvm/Support/ArrayRecycler.h"
2324 #include "llvm/Support/DebugLoc.h"
2425 #include "llvm/Support/Recycler.h"
2526
104105 // Allocation management for instructions in function.
105106 Recycler InstructionRecycler;
106107
108 // Allocation management for operand arrays on instructions.
109 ArrayRecycler OperandRecycler;
110
107111 // Allocation management for basic blocks in function.
108112 Recycler BasicBlockRecycler;
109113
393397 MachineMemOperand *getMachineMemOperand(const MachineMemOperand *MMO,
394398 int64_t Offset, uint64_t Size);
395399
400 typedef ArrayRecycler::Capacity OperandCapacity;
401
402 /// Allocate an array of MachineOperands. This is only intended for use by
403 /// internal MachineInstr functions.
404 MachineOperand *allocateOperandArray(OperandCapacity Cap) {
405 return OperandRecycler.allocate(Cap, Allocator);
406 }
407
408 /// Dellocate an array of MachineOperands and recycle the memory. This is
409 /// only intended for use by internal MachineInstr functions.
410 /// Cap must be the same capacity that was used to allocate the array.
411 void deallocateOperandArray(OperandCapacity Cap, MachineOperand *Array) {
412 OperandRecycler.deallocate(Cap, Array);
413 }
414
396415 /// allocateMemRefsArray - Allocate an array to hold MachineMemOperand
397416 /// pointers. This array is owned by the MachineFunction.
398417 MachineInstr::mmo_iterator allocateMemRefsArray(unsigned long Num);
2424 #include "llvm/CodeGen/MachineOperand.h"
2525 #include "llvm/IR/InlineAsm.h"
2626 #include "llvm/MC/MCInstrDesc.h"
27 #include "llvm/Support/ArrayRecycler.h"
2728 #include "llvm/Support/DebugLoc.h"
2829 #include "llvm/Target/TargetOpcodes.h"
2930 #include
6263 };
6364 private:
6465 const MCInstrDesc *MCID; // Instruction descriptor.
66 MachineBasicBlock *Parent; // Pointer to the owning basic block.
67
68 // Operands are allocated by an ArrayRecycler.
69 MachineOperand *Operands; // Pointer to the first operand.
70 unsigned NumOperands; // Number of operands on instruction.
71 typedef ArrayRecycler::Capacity OperandCapacity;
72 OperandCapacity CapOperands; // Capacity of the Operands array.
6573
6674 uint8_t Flags; // Various bits of additional
6775 // information about machine
7785 uint16_t NumMemRefs; // information on memory references
7886 mmo_iterator MemRefs;
7987
80 std::vector Operands; // the operands
81 MachineBasicBlock *Parent; // Pointer to the owning basic block.
8288 DebugLoc debugLoc; // Source line information.
8389
8490 MachineInstr(const MachineInstr&) LLVM_DELETED_FUNCTION;
251257
252258 /// Access to explicit operands of the instruction.
253259 ///
254 unsigned getNumOperands() const { return (unsigned)Operands.size(); }
260 unsigned getNumOperands() const { return NumOperands; }
255261
256262 const MachineOperand& getOperand(unsigned i) const {
257263 assert(i < getNumOperands() && "getOperand() out of range!");
267273 unsigned getNumExplicitOperands() const;
268274
269275 /// iterator/begin/end - Iterate over all operands of a machine instruction.
270 typedef std::vector::iterator mop_iterator;
271 typedef std::vector::const_iterator const_mop_iterator;
272
273 mop_iterator operands_begin() { return Operands.begin(); }
274 mop_iterator operands_end() { return Operands.end(); }
275
276 const_mop_iterator operands_begin() const { return Operands.begin(); }
277 const_mop_iterator operands_end() const { return Operands.end(); }
276 typedef MachineOperand *mop_iterator;
277 typedef const MachineOperand *const_mop_iterator;
278
279 mop_iterator operands_begin() { return Operands; }
280 mop_iterator operands_end() { return Operands + NumOperands; }
281
282 const_mop_iterator operands_begin() const { return Operands; }
283 const_mop_iterator operands_end() const { return Operands + NumOperands; }
278284
279285 /// Access to memory operands of the instruction
280286 mmo_iterator memoperands_begin() const { return MemRefs; }
3333 class MCSymbol;
3434
3535 /// MachineOperand class - Representation of each machine instruction operand.
36 ///
37 /// This class isn't a POD type because it has a private constructor, but its
38 /// destructor must be trivial. Functions like MachineInstr::addOperand(),
39 /// MachineRegisterInfo::moveOperands(), and MF::DeleteMachineInstr() depend on
40 /// not having to call the MachineOperand destructor.
3641 ///
3742 class MachineOperand {
3843 public:
7777 MachineFunction::~MachineFunction() {
7878 BasicBlocks.clear();
7979 InstructionRecycler.clear(Allocator);
80 OperandRecycler.clear(Allocator);
8081 BasicBlockRecycler.clear(Allocator);
8182 if (RegInfo) {
8283 RegInfo->~MachineRegisterInfo();
176177 ///
177178 void
178179 MachineFunction::DeleteMachineInstr(MachineInstr *MI) {
180 // Strip it for parts. The operand array and the MI object itself are
181 // independently recyclable.
182 if (MI->Operands)
183 deallocateOperandArray(MI->CapOperands, MI->Operands);
184 MI->Operands = 0;
185 MI->NumOperands = 0;
179186 MI->~MachineInstr();
180187 InstructionRecycler.Deallocate(Allocator, MI);
181188 }
531531 /// the MCInstrDesc.
532532 MachineInstr::MachineInstr(MachineFunction &MF, const MCInstrDesc &tid,
533533 const DebugLoc dl, bool NoImp)
534 : MCID(&tid), Flags(0), AsmPrinterFlags(0),
535 NumMemRefs(0), MemRefs(0), Parent(0), debugLoc(dl) {
536 unsigned NumImplicitOps = 0;
537 if (!NoImp)
538 NumImplicitOps = MCID->getNumImplicitDefs() + MCID->getNumImplicitUses();
539 Operands.reserve(NumImplicitOps + MCID->getNumOperands());
534 : MCID(&tid), Parent(0), Operands(0), NumOperands(0),
535 Flags(0), AsmPrinterFlags(0),
536 NumMemRefs(0), MemRefs(0), debugLoc(dl) {
537 // Reserve space for the expected number of operands.
538 if (unsigned NumOps = MCID->getNumOperands() +
539 MCID->getNumImplicitDefs() + MCID->getNumImplicitUses()) {
540 CapOperands = OperandCapacity::get(NumOps);
541 Operands = MF.allocateOperandArray(CapOperands);
542 }
543
540544 if (!NoImp)
541545 addImplicitDefUseOperands(MF);
542546 // Make sure that we get added to a machine basicblock
546550 /// MachineInstr ctor - Copies MachineInstr arg exactly
547551 ///
548552 MachineInstr::MachineInstr(MachineFunction &MF, const MachineInstr &MI)
549 : MCID(&MI.getDesc()), Flags(0), AsmPrinterFlags(0),
553 : MCID(&MI.getDesc()), Parent(0), Operands(0), NumOperands(0),
554 Flags(0), AsmPrinterFlags(0),
550555 NumMemRefs(MI.NumMemRefs), MemRefs(MI.MemRefs),
551 Parent(0), debugLoc(MI.getDebugLoc()) {
552 Operands.reserve(MI.getNumOperands());
556 debugLoc(MI.getDebugLoc()) {
557 CapOperands = OperandCapacity::get(MI.getNumOperands());
558 Operands = MF.allocateOperandArray(CapOperands);
553559
554560 // Add operands
555561 for (unsigned i = 0; i != MI.getNumOperands(); ++i)
610616 addOperand(*MF, Op);
611617 }
612618
619 /// Move NumOps MachineOperands from Src to Dst, with support for overlapping
620 /// ranges. If MRI is non-null also update use-def chains.
621 static void moveOperands(MachineOperand *Dst, MachineOperand *Src,
622 unsigned NumOps, MachineRegisterInfo *MRI) {
623 if (MRI)
624 return MRI->moveOperands(Dst, Src, NumOps);
625
626 // Here it would be convenient to call memmove, so that isn't allowed because
627 // MachineOperand has a constructor and so isn't a POD type.
628 if (Dst < Src)
629 for (unsigned i = 0; i != NumOps; ++i)
630 new (Dst + i) MachineOperand(Src[i]);
631 else
632 for (unsigned i = NumOps; i ; --i)
633 new (Dst + i - 1) MachineOperand(Src[i - 1]);
634 }
635
613636 /// addOperand - Add the specified operand to the instruction. If it is an
614637 /// implicit operand, it is added to the end of the operand list. If it is
615638 /// an explicit operand it is added at the end of the explicit operand list
616639 /// (before the first implicit operand).
617640 void MachineInstr::addOperand(MachineFunction &MF, const MachineOperand &Op) {
618641 assert(MCID && "Cannot add operands before providing an instr descriptor");
619 bool isImpReg = Op.isReg() && Op.isImplicit();
620 MachineRegisterInfo *RegInfo = getRegInfo();
621
622 // If the Operands backing store is reallocated, all register operands must
623 // be removed and re-added to RegInfo. It is storing pointers to operands.
624 bool Reallocate = RegInfo &&
625 !Operands.empty() && getNumOperands() == Operands.capacity();
642
643 // Check if we're adding one of our existing operands.
644 if (&Op >= Operands && &Op < Operands + NumOperands) {
645 // This is unusual: MI->addOperand(MI->getOperand(i)).
646 // If adding Op requires reallocating or moving existing operands around,
647 // the Op reference could go stale. Support it by copying Op.
648 MachineOperand CopyOp(Op);
649 return addOperand(MF, CopyOp);
650 }
626651
627652 // Find the insert location for the new operand. Implicit registers go at
628 // the end, everything goes before the implicit regs.
629 unsigned OpNo = getNumOperands();
630
631 // Remove all the implicit operands from RegInfo if they need to be shifted.
653 // the end, everything else goes before the implicit regs.
654 //
632655 // FIXME: Allow mixed explicit and implicit operands on inline asm.
633656 // InstrEmitter::EmitSpecialNode() is marking inline asm clobbers as
634657 // implicit-defs, but they must not be moved around. See the FIXME in
635658 // InstrEmitter.cpp.
659 unsigned OpNo = getNumOperands();
660 bool isImpReg = Op.isReg() && Op.isImplicit();
636661 if (!isImpReg && !isInlineAsm()) {
637662 while (OpNo && Operands[OpNo-1].isReg() && Operands[OpNo-1].isImplicit()) {
638663 --OpNo;
639664 assert(!Operands[OpNo].isTied() && "Cannot move tied operands");
640 if (RegInfo)
641 RegInfo->removeRegOperandFromUseList(&Operands[OpNo]);
642665 }
643666 }
644667
649672 OpNo < MCID->getNumOperands()) &&
650673 "Trying to add an operand to a machine instr that is already done!");
651674
652 // All operands from OpNo have been removed from RegInfo. If the Operands
653 // backing store needs to be reallocated, we also need to remove any other
654 // register operands.
655 if (Reallocate)
656 for (unsigned i = 0; i != OpNo; ++i)
657 if (Operands[i].isReg())
658 RegInfo->removeRegOperandFromUseList(&Operands[i]);
659
660 // Insert the new operand at OpNo.
661 Operands.insert(Operands.begin() + OpNo, Op);
662 Operands[OpNo].ParentMI = this;
663
664 // The Operands backing store has now been reallocated, so we can re-add the
665 // operands before OpNo.
666 if (Reallocate)
667 for (unsigned i = 0; i != OpNo; ++i)
668 if (Operands[i].isReg())
669 RegInfo->addRegOperandToUseList(&Operands[i]);
670
671 // When adding a register operand, tell RegInfo about it.
672 if (Operands[OpNo].isReg()) {
675 MachineRegisterInfo *MRI = getRegInfo();
676
677 // Determine if the Operands array needs to be reallocated.
678 // Save the old capacity and operand array.
679 OperandCapacity OldCap = CapOperands;
680 MachineOperand *OldOperands = Operands;
681 if (!OldOperands || OldCap.getSize() == getNumOperands()) {
682 CapOperands = OldOperands ? OldCap.getNext() : OldCap.get(1);
683 Operands = MF.allocateOperandArray(CapOperands);
684 // Move the operands before the insertion point.
685 if (OpNo)
686 moveOperands(Operands, OldOperands, OpNo, MRI);
687 }
688
689 // Move the operands following the insertion point.
690 if (OpNo != NumOperands)
691 moveOperands(Operands + OpNo + 1, OldOperands + OpNo, NumOperands - OpNo,
692 MRI);
693 ++NumOperands;
694
695 // Deallocate the old operand array.
696 if (OldOperands != Operands && OldOperands)
697 MF.deallocateOperandArray(OldCap, OldOperands);
698
699 // Copy Op into place. It still needs to be inserted into the MRI use lists.
700 MachineOperand *NewMO = new (Operands + OpNo) MachineOperand(Op);
701 NewMO->ParentMI = this;
702
703 // When adding a register operand, tell MRI about it.
704 if (NewMO->isReg()) {
673705 // Ensure isOnRegUseList() returns false, regardless of Op's status.
674 Operands[OpNo].Contents.Reg.Prev = 0;
706 NewMO->Contents.Reg.Prev = 0;
675707 // Ignore existing ties. This is not a property that can be copied.
676 Operands[OpNo].TiedTo = 0;
677 // Add the new operand to RegInfo.
678 if (RegInfo)
679 RegInfo->addRegOperandToUseList(&Operands[OpNo]);
708 NewMO->TiedTo = 0;
709 // Add the new operand to MRI, but only for instructions in an MBB.
710 if (MRI)
711 MRI->addRegOperandToUseList(NewMO);
680712 // The MCID operand information isn't accurate until we start adding
681713 // explicit operands. The implicit operands are added first, then the
682714 // explicits are inserted before them.
683715 if (!isImpReg) {
684716 // Tie uses to defs as indicated in MCInstrDesc.
685 if (Operands[OpNo].isUse()) {
717 if (NewMO->isUse()) {
686718 int DefIdx = MCID->getOperandConstraint(OpNo, MCOI::TIED_TO);
687719 if (DefIdx != -1)
688720 tieOperands(DefIdx, OpNo);
689721 }
690722 // If the register operand is flagged as early, mark the operand as such.
691723 if (MCID->getOperandConstraint(OpNo, MCOI::EARLY_CLOBBER) != -1)
692 Operands[OpNo].setIsEarlyClobber(true);
693 }
694 }
695
696 // Re-add all the implicit ops.
697 if (RegInfo) {
698 for (unsigned i = OpNo + 1, e = getNumOperands(); i != e; ++i) {
699 assert(Operands[i].isReg() && "Should only be an implicit reg!");
700 RegInfo->addRegOperandToUseList(&Operands[i]);
724 NewMO->setIsEarlyClobber(true);
701725 }
702726 }
703727 }
708732 void MachineInstr::RemoveOperand(unsigned OpNo) {
709733 assert(OpNo < getNumOperands() && "Invalid operand number");
710734 untieRegOperand(OpNo);
711 MachineRegisterInfo *RegInfo = getRegInfo();
712
713 // If we have reginfo to update, remove all operands that will be shifted
714 // down from their reg lists, move everything down, then re-add them.
715 if (RegInfo) {
716 for (unsigned i = OpNo, e = getNumOperands(); i != e; ++i) {
717 if (Operands[i].isReg())
718 RegInfo->removeRegOperandFromUseList(&Operands[i]);
719 }
720 }
721735
722736 #ifndef NDEBUG
723737 // Moving tied operands would break the ties.
726740 assert(!Operands[i].isTied() && "Cannot move tied operands");
727741 #endif
728742
729 Operands.erase(Operands.begin()+OpNo);
730
731 if (RegInfo) {
732 for (unsigned i = OpNo, e = getNumOperands(); i != e; ++i) {
733 if (Operands[i].isReg())
734 RegInfo->addRegOperandToUseList(&Operands[i]);
735 }
736 }
743 MachineRegisterInfo *MRI = getRegInfo();
744 if (MRI && Operands[OpNo].isReg())
745 MRI->removeRegOperandFromUseList(Operands + OpNo);
746
747 // Don't call the MachineOperand destructor. A lot of this code depends on
748 // MachineOperand having a trivial destructor anyway, and adding a call here
749 // wouldn't make it 'destructor-correct'.
750
751 if (unsigned N = NumOperands - 1 - OpNo)
752 moveOperands(Operands + OpNo, Operands + OpNo + 1, N, MRI);
753 --NumOperands;
737754 }
738755
739756 /// addMemOperand - Add a MachineMemOperand to the machine instruction.