12cab237bSDimitry Andric //===- MachineFunction.cpp ------------------------------------------------===//
2f22ef01cSRoman Divacky //
3f22ef01cSRoman Divacky // The LLVM Compiler Infrastructure
4f22ef01cSRoman Divacky //
5f22ef01cSRoman Divacky // This file is distributed under the University of Illinois Open Source
6f22ef01cSRoman Divacky // License. See LICENSE.TXT for details.
7f22ef01cSRoman Divacky //
8f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
9f22ef01cSRoman Divacky //
10f22ef01cSRoman Divacky // Collect native machine code information for a function. This allows
11f22ef01cSRoman Divacky // target-specific information about the generated code to be stored with each
12f22ef01cSRoman Divacky // function.
13f22ef01cSRoman Divacky //
14f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
15f22ef01cSRoman Divacky
16f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineFunction.h"
172cab237bSDimitry Andric #include "llvm/ADT/BitVector.h"
182cab237bSDimitry Andric #include "llvm/ADT/DenseMap.h"
192cab237bSDimitry Andric #include "llvm/ADT/DenseSet.h"
20139f7f9bSDimitry Andric #include "llvm/ADT/STLExtras.h"
21139f7f9bSDimitry Andric #include "llvm/ADT/SmallString.h"
222cab237bSDimitry Andric #include "llvm/ADT/SmallVector.h"
232cab237bSDimitry Andric #include "llvm/ADT/StringRef.h"
242cab237bSDimitry Andric #include "llvm/ADT/Twine.h"
25139f7f9bSDimitry Andric #include "llvm/Analysis/ConstantFolding.h"
267d523365SDimitry Andric #include "llvm/Analysis/EHPersonalities.h"
272cab237bSDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
28dff0c46cSDimitry Andric #include "llvm/CodeGen/MachineConstantPool.h"
29f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineFrameInfo.h"
30f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineInstr.h"
31f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineJumpTableInfo.h"
322cab237bSDimitry Andric #include "llvm/CodeGen/MachineMemOperand.h"
33f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineModuleInfo.h"
34f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineRegisterInfo.h"
357d523365SDimitry Andric #include "llvm/CodeGen/PseudoSourceValue.h"
362cab237bSDimitry Andric #include "llvm/CodeGen/TargetFrameLowering.h"
372cab237bSDimitry Andric #include "llvm/CodeGen/TargetLowering.h"
382cab237bSDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
392cab237bSDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
404ba319b5SDimitry Andric #include "llvm/CodeGen/WasmEHFuncInfo.h"
417d523365SDimitry Andric #include "llvm/CodeGen/WinEHFuncInfo.h"
424ba319b5SDimitry Andric #include "llvm/Config/llvm-config.h"
432cab237bSDimitry Andric #include "llvm/IR/Attributes.h"
442cab237bSDimitry Andric #include "llvm/IR/BasicBlock.h"
452cab237bSDimitry Andric #include "llvm/IR/Constant.h"
46139f7f9bSDimitry Andric #include "llvm/IR/DataLayout.h"
472cab237bSDimitry Andric #include "llvm/IR/DerivedTypes.h"
48139f7f9bSDimitry Andric #include "llvm/IR/Function.h"
492cab237bSDimitry Andric #include "llvm/IR/GlobalValue.h"
502cab237bSDimitry Andric #include "llvm/IR/Instruction.h"
512cab237bSDimitry Andric #include "llvm/IR/Instructions.h"
522cab237bSDimitry Andric #include "llvm/IR/Metadata.h"
53875ed548SDimitry Andric #include "llvm/IR/Module.h"
543dac3a9bSDimitry Andric #include "llvm/IR/ModuleSlotTracker.h"
552cab237bSDimitry Andric #include "llvm/IR/Value.h"
56f22ef01cSRoman Divacky #include "llvm/MC/MCContext.h"
572cab237bSDimitry Andric #include "llvm/MC/MCSymbol.h"
582cab237bSDimitry Andric #include "llvm/MC/SectionKind.h"
592cab237bSDimitry Andric #include "llvm/Support/Casting.h"
602cab237bSDimitry Andric #include "llvm/Support/CommandLine.h"
612cab237bSDimitry Andric #include "llvm/Support/Compiler.h"
622cab237bSDimitry Andric #include "llvm/Support/DOTGraphTraits.h"
63f22ef01cSRoman Divacky #include "llvm/Support/Debug.h"
642cab237bSDimitry Andric #include "llvm/Support/ErrorHandling.h"
65f22ef01cSRoman Divacky #include "llvm/Support/GraphWriter.h"
66f22ef01cSRoman Divacky #include "llvm/Support/raw_ostream.h"
67139f7f9bSDimitry Andric #include "llvm/Target/TargetMachine.h"
682cab237bSDimitry Andric #include <algorithm>
692cab237bSDimitry Andric #include <cassert>
702cab237bSDimitry Andric #include <cstddef>
712cab237bSDimitry Andric #include <cstdint>
722cab237bSDimitry Andric #include <iterator>
732cab237bSDimitry Andric #include <string>
742cab237bSDimitry Andric #include <utility>
752cab237bSDimitry Andric #include <vector>
762cab237bSDimitry Andric
77f22ef01cSRoman Divacky using namespace llvm;
78f22ef01cSRoman Divacky
7991bc56edSDimitry Andric #define DEBUG_TYPE "codegen"
8091bc56edSDimitry Andric
817d523365SDimitry Andric static cl::opt<unsigned>
827d523365SDimitry Andric AlignAllFunctions("align-all-functions",
837d523365SDimitry Andric cl::desc("Force the alignment of all functions."),
847d523365SDimitry Andric cl::init(0), cl::Hidden);
857d523365SDimitry Andric
getPropertyName(MachineFunctionProperties::Property Prop)86d88c1a5aSDimitry Andric static const char *getPropertyName(MachineFunctionProperties::Property Prop) {
872cab237bSDimitry Andric using P = MachineFunctionProperties::Property;
882cab237bSDimitry Andric
89d88c1a5aSDimitry Andric switch(Prop) {
90d88c1a5aSDimitry Andric case P::FailedISel: return "FailedISel";
91d88c1a5aSDimitry Andric case P::IsSSA: return "IsSSA";
92d88c1a5aSDimitry Andric case P::Legalized: return "Legalized";
93d88c1a5aSDimitry Andric case P::NoPHIs: return "NoPHIs";
94d88c1a5aSDimitry Andric case P::NoVRegs: return "NoVRegs";
95d88c1a5aSDimitry Andric case P::RegBankSelected: return "RegBankSelected";
96d88c1a5aSDimitry Andric case P::Selected: return "Selected";
97d88c1a5aSDimitry Andric case P::TracksLiveness: return "TracksLiveness";
98d88c1a5aSDimitry Andric }
99d88c1a5aSDimitry Andric llvm_unreachable("Invalid machine function property");
100d88c1a5aSDimitry Andric }
101d88c1a5aSDimitry Andric
102*b5893f02SDimitry Andric // Pin the vtable to this file.
anchor()103*b5893f02SDimitry Andric void MachineFunction::Delegate::anchor() {}
104*b5893f02SDimitry Andric
print(raw_ostream & OS) const105d88c1a5aSDimitry Andric void MachineFunctionProperties::print(raw_ostream &OS) const {
106d88c1a5aSDimitry Andric const char *Separator = "";
107d88c1a5aSDimitry Andric for (BitVector::size_type I = 0; I < Properties.size(); ++I) {
108d88c1a5aSDimitry Andric if (!Properties[I])
1093ca95b02SDimitry Andric continue;
110d88c1a5aSDimitry Andric OS << Separator << getPropertyName(static_cast<Property>(I));
111d88c1a5aSDimitry Andric Separator = ", ";
1123ca95b02SDimitry Andric }
1133ca95b02SDimitry Andric }
1143ca95b02SDimitry Andric
115f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
116f22ef01cSRoman Divacky // MachineFunction implementation
117f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
118f22ef01cSRoman Divacky
1198f0fd8f6SDimitry Andric // Out-of-line virtual method.
1202cab237bSDimitry Andric MachineFunctionInfo::~MachineFunctionInfo() = default;
121f22ef01cSRoman Divacky
deleteNode(MachineBasicBlock * MBB)122d88c1a5aSDimitry Andric void ilist_alloc_traits<MachineBasicBlock>::deleteNode(MachineBasicBlock *MBB) {
123f22ef01cSRoman Divacky MBB->getParent()->DeleteMachineBasicBlock(MBB);
124f22ef01cSRoman Divacky }
125f22ef01cSRoman Divacky
getFnStackAlignment(const TargetSubtargetInfo * STI,const Function & F)1263ca95b02SDimitry Andric static inline unsigned getFnStackAlignment(const TargetSubtargetInfo *STI,
1272cab237bSDimitry Andric const Function &F) {
1282cab237bSDimitry Andric if (F.hasFnAttribute(Attribute::StackAlignment))
1292cab237bSDimitry Andric return F.getFnStackAlignment();
1303ca95b02SDimitry Andric return STI->getFrameLowering()->getStackAlignment();
1313ca95b02SDimitry Andric }
1323ca95b02SDimitry Andric
MachineFunction(const Function & F,const LLVMTargetMachine & Target,const TargetSubtargetInfo & STI,unsigned FunctionNum,MachineModuleInfo & mmi)133*b5893f02SDimitry Andric MachineFunction::MachineFunction(const Function &F,
134*b5893f02SDimitry Andric const LLVMTargetMachine &Target,
1352cab237bSDimitry Andric const TargetSubtargetInfo &STI,
13639d628a0SDimitry Andric unsigned FunctionNum, MachineModuleInfo &mmi)
1372cab237bSDimitry Andric : F(F), Target(Target), STI(&STI), Ctx(mmi.getContext()), MMI(mmi) {
138d88c1a5aSDimitry Andric FunctionNumber = FunctionNum;
139d88c1a5aSDimitry Andric init();
140d88c1a5aSDimitry Andric }
141d88c1a5aSDimitry Andric
handleInsertion(MachineInstr & MI)142*b5893f02SDimitry Andric void MachineFunction::handleInsertion(MachineInstr &MI) {
143*b5893f02SDimitry Andric if (TheDelegate)
144*b5893f02SDimitry Andric TheDelegate->MF_HandleInsertion(MI);
145*b5893f02SDimitry Andric }
146*b5893f02SDimitry Andric
handleRemoval(MachineInstr & MI)147*b5893f02SDimitry Andric void MachineFunction::handleRemoval(MachineInstr &MI) {
148*b5893f02SDimitry Andric if (TheDelegate)
149*b5893f02SDimitry Andric TheDelegate->MF_HandleRemoval(MI);
150*b5893f02SDimitry Andric }
151*b5893f02SDimitry Andric
init()152d88c1a5aSDimitry Andric void MachineFunction::init() {
1533ca95b02SDimitry Andric // Assume the function starts in SSA form with correct liveness.
1543ca95b02SDimitry Andric Properties.set(MachineFunctionProperties::Property::IsSSA);
1553ca95b02SDimitry Andric Properties.set(MachineFunctionProperties::Property::TracksLiveness);
15639d628a0SDimitry Andric if (STI->getRegisterInfo())
15739d628a0SDimitry Andric RegInfo = new (Allocator) MachineRegisterInfo(this);
158f22ef01cSRoman Divacky else
15991bc56edSDimitry Andric RegInfo = nullptr;
160f785676fSDimitry Andric
16191bc56edSDimitry Andric MFInfo = nullptr;
1623ca95b02SDimitry Andric // We can realign the stack if the target supports it and the user hasn't
1633ca95b02SDimitry Andric // explicitly asked us not to.
1643ca95b02SDimitry Andric bool CanRealignSP = STI->getFrameLowering()->isStackRealignable() &&
1652cab237bSDimitry Andric !F.hasFnAttribute("no-realign-stack");
1663ca95b02SDimitry Andric FrameInfo = new (Allocator) MachineFrameInfo(
1672cab237bSDimitry Andric getFnStackAlignment(STI, F), /*StackRealignable=*/CanRealignSP,
1683ca95b02SDimitry Andric /*ForceRealign=*/CanRealignSP &&
1692cab237bSDimitry Andric F.hasFnAttribute(Attribute::StackAlignment));
170f785676fSDimitry Andric
1712cab237bSDimitry Andric if (F.hasFnAttribute(Attribute::StackAlignment))
1722cab237bSDimitry Andric FrameInfo->ensureMaxAlignment(F.getFnStackAlignment());
173f785676fSDimitry Andric
174875ed548SDimitry Andric ConstantPool = new (Allocator) MachineConstantPool(getDataLayout());
17539d628a0SDimitry Andric Alignment = STI->getTargetLowering()->getMinFunctionAlignment();
176f785676fSDimitry Andric
1772cab237bSDimitry Andric // FIXME: Shouldn't use pref alignment if explicit alignment is set on F.
1787d523365SDimitry Andric // FIXME: Use Function::optForSize().
1792cab237bSDimitry Andric if (!F.hasFnAttribute(Attribute::OptimizeForSize))
180bd5abe19SDimitry Andric Alignment = std::max(Alignment,
18139d628a0SDimitry Andric STI->getTargetLowering()->getPrefFunctionAlignment());
182f785676fSDimitry Andric
1837d523365SDimitry Andric if (AlignAllFunctions)
1847d523365SDimitry Andric Alignment = AlignAllFunctions;
1857d523365SDimitry Andric
18691bc56edSDimitry Andric JumpTableInfo = nullptr;
1877d523365SDimitry Andric
1887d523365SDimitry Andric if (isFuncletEHPersonality(classifyEHPersonality(
1892cab237bSDimitry Andric F.hasPersonalityFn() ? F.getPersonalityFn() : nullptr))) {
1907d523365SDimitry Andric WinEHInfo = new (Allocator) WinEHFuncInfo();
1917d523365SDimitry Andric }
1927d523365SDimitry Andric
1934ba319b5SDimitry Andric if (isScopedEHPersonality(classifyEHPersonality(
1944ba319b5SDimitry Andric F.hasPersonalityFn() ? F.getPersonalityFn() : nullptr))) {
1954ba319b5SDimitry Andric WasmEHInfo = new (Allocator) WasmEHFuncInfo();
1964ba319b5SDimitry Andric }
1974ba319b5SDimitry Andric
198d88c1a5aSDimitry Andric assert(Target.isCompatibleDataLayout(getDataLayout()) &&
1997d523365SDimitry Andric "Can't create a MachineFunction using a Module with a "
2007d523365SDimitry Andric "Target-incompatible DataLayout attached\n");
2017d523365SDimitry Andric
2022cab237bSDimitry Andric PSVManager =
2032cab237bSDimitry Andric llvm::make_unique<PseudoSourceValueManager>(*(getSubtarget().
2042cab237bSDimitry Andric getInstrInfo()));
205f22ef01cSRoman Divacky }
206f22ef01cSRoman Divacky
~MachineFunction()207f22ef01cSRoman Divacky MachineFunction::~MachineFunction() {
208d88c1a5aSDimitry Andric clear();
209d88c1a5aSDimitry Andric }
210d88c1a5aSDimitry Andric
clear()211d88c1a5aSDimitry Andric void MachineFunction::clear() {
212d88c1a5aSDimitry Andric Properties.reset();
213139f7f9bSDimitry Andric // Don't call destructors on MachineInstr and MachineOperand. All of their
214139f7f9bSDimitry Andric // memory comes from the BumpPtrAllocator which is about to be purged.
215139f7f9bSDimitry Andric //
216139f7f9bSDimitry Andric // Do call MachineBasicBlock destructors, it contains std::vectors.
217139f7f9bSDimitry Andric for (iterator I = begin(), E = end(); I != E; I = BasicBlocks.erase(I))
218139f7f9bSDimitry Andric I->Insts.clearAndLeakNodesUnsafely();
2194ba319b5SDimitry Andric MBBNumbering.clear();
220139f7f9bSDimitry Andric
221f22ef01cSRoman Divacky InstructionRecycler.clear(Allocator);
222139f7f9bSDimitry Andric OperandRecycler.clear(Allocator);
223f22ef01cSRoman Divacky BasicBlockRecycler.clear(Allocator);
2242cab237bSDimitry Andric CodeViewAnnotations.clear();
2257a7e6055SDimitry Andric VariableDbgInfos.clear();
226f22ef01cSRoman Divacky if (RegInfo) {
227f22ef01cSRoman Divacky RegInfo->~MachineRegisterInfo();
228f22ef01cSRoman Divacky Allocator.Deallocate(RegInfo);
229f22ef01cSRoman Divacky }
230f22ef01cSRoman Divacky if (MFInfo) {
231f22ef01cSRoman Divacky MFInfo->~MachineFunctionInfo();
232f22ef01cSRoman Divacky Allocator.Deallocate(MFInfo);
233f22ef01cSRoman Divacky }
2347ae0e2c9SDimitry Andric
2357ae0e2c9SDimitry Andric FrameInfo->~MachineFrameInfo();
2367ae0e2c9SDimitry Andric Allocator.Deallocate(FrameInfo);
2377ae0e2c9SDimitry Andric
2387ae0e2c9SDimitry Andric ConstantPool->~MachineConstantPool();
2397ae0e2c9SDimitry Andric Allocator.Deallocate(ConstantPool);
240f22ef01cSRoman Divacky
241f22ef01cSRoman Divacky if (JumpTableInfo) {
242f22ef01cSRoman Divacky JumpTableInfo->~MachineJumpTableInfo();
243f22ef01cSRoman Divacky Allocator.Deallocate(JumpTableInfo);
244f22ef01cSRoman Divacky }
2457d523365SDimitry Andric
2467d523365SDimitry Andric if (WinEHInfo) {
2477d523365SDimitry Andric WinEHInfo->~WinEHFuncInfo();
2487d523365SDimitry Andric Allocator.Deallocate(WinEHInfo);
2497d523365SDimitry Andric }
250*b5893f02SDimitry Andric
251*b5893f02SDimitry Andric if (WasmEHInfo) {
252*b5893f02SDimitry Andric WasmEHInfo->~WasmEHFuncInfo();
253*b5893f02SDimitry Andric Allocator.Deallocate(WasmEHInfo);
254*b5893f02SDimitry Andric }
255f22ef01cSRoman Divacky }
256f22ef01cSRoman Divacky
getDataLayout() const257875ed548SDimitry Andric const DataLayout &MachineFunction::getDataLayout() const {
2582cab237bSDimitry Andric return F.getParent()->getDataLayout();
259875ed548SDimitry Andric }
260875ed548SDimitry Andric
2618f0fd8f6SDimitry Andric /// Get the JumpTableInfo for this function.
2628f0fd8f6SDimitry Andric /// If it does not already exist, allocate one.
263f22ef01cSRoman Divacky MachineJumpTableInfo *MachineFunction::
getOrCreateJumpTableInfo(unsigned EntryKind)264f22ef01cSRoman Divacky getOrCreateJumpTableInfo(unsigned EntryKind) {
265f22ef01cSRoman Divacky if (JumpTableInfo) return JumpTableInfo;
266f22ef01cSRoman Divacky
267f22ef01cSRoman Divacky JumpTableInfo = new (Allocator)
268f22ef01cSRoman Divacky MachineJumpTableInfo((MachineJumpTableInfo::JTEntryKind)EntryKind);
269f22ef01cSRoman Divacky return JumpTableInfo;
270f22ef01cSRoman Divacky }
271f22ef01cSRoman Divacky
27291bc56edSDimitry Andric /// Should we be emitting segmented stack stuff for the function
shouldSplitStack() const2738c24ff90SDimitry Andric bool MachineFunction::shouldSplitStack() const {
2742cab237bSDimitry Andric return getFunction().hasFnAttribute("split-stack");
27591bc56edSDimitry Andric }
27691bc56edSDimitry Andric
2778f0fd8f6SDimitry Andric /// This discards all of the MachineBasicBlock numbers and recomputes them.
2788f0fd8f6SDimitry Andric /// This guarantees that the MBB numbers are sequential, dense, and match the
2798f0fd8f6SDimitry Andric /// ordering of the blocks within the function. If a specific MachineBasicBlock
2808f0fd8f6SDimitry Andric /// is specified, only that block and those after it are renumbered.
RenumberBlocks(MachineBasicBlock * MBB)281f22ef01cSRoman Divacky void MachineFunction::RenumberBlocks(MachineBasicBlock *MBB) {
282f22ef01cSRoman Divacky if (empty()) { MBBNumbering.clear(); return; }
283f22ef01cSRoman Divacky MachineFunction::iterator MBBI, E = end();
28491bc56edSDimitry Andric if (MBB == nullptr)
285f22ef01cSRoman Divacky MBBI = begin();
286f22ef01cSRoman Divacky else
2877d523365SDimitry Andric MBBI = MBB->getIterator();
288f22ef01cSRoman Divacky
289f22ef01cSRoman Divacky // Figure out the block number this should have.
290f22ef01cSRoman Divacky unsigned BlockNo = 0;
291f22ef01cSRoman Divacky if (MBBI != begin())
29291bc56edSDimitry Andric BlockNo = std::prev(MBBI)->getNumber() + 1;
293f22ef01cSRoman Divacky
294f22ef01cSRoman Divacky for (; MBBI != E; ++MBBI, ++BlockNo) {
295f22ef01cSRoman Divacky if (MBBI->getNumber() != (int)BlockNo) {
296f22ef01cSRoman Divacky // Remove use of the old number.
297f22ef01cSRoman Divacky if (MBBI->getNumber() != -1) {
298f22ef01cSRoman Divacky assert(MBBNumbering[MBBI->getNumber()] == &*MBBI &&
299f22ef01cSRoman Divacky "MBB number mismatch!");
30091bc56edSDimitry Andric MBBNumbering[MBBI->getNumber()] = nullptr;
301f22ef01cSRoman Divacky }
302f22ef01cSRoman Divacky
303f22ef01cSRoman Divacky // If BlockNo is already taken, set that block's number to -1.
304f22ef01cSRoman Divacky if (MBBNumbering[BlockNo])
305f22ef01cSRoman Divacky MBBNumbering[BlockNo]->setNumber(-1);
306f22ef01cSRoman Divacky
3077d523365SDimitry Andric MBBNumbering[BlockNo] = &*MBBI;
308f22ef01cSRoman Divacky MBBI->setNumber(BlockNo);
309f22ef01cSRoman Divacky }
310f22ef01cSRoman Divacky }
311f22ef01cSRoman Divacky
312f22ef01cSRoman Divacky // Okay, all the blocks are renumbered. If we have compactified the block
313f22ef01cSRoman Divacky // numbering, shrink MBBNumbering now.
314f22ef01cSRoman Divacky assert(BlockNo <= MBBNumbering.size() && "Mismatch!");
315f22ef01cSRoman Divacky MBBNumbering.resize(BlockNo);
316f22ef01cSRoman Divacky }
317f22ef01cSRoman Divacky
3188f0fd8f6SDimitry Andric /// Allocate a new MachineInstr. Use this instead of `new MachineInstr'.
CreateMachineInstr(const MCInstrDesc & MCID,const DebugLoc & DL,bool NoImp)3193ca95b02SDimitry Andric MachineInstr *MachineFunction::CreateMachineInstr(const MCInstrDesc &MCID,
3203ca95b02SDimitry Andric const DebugLoc &DL,
3213ca95b02SDimitry Andric bool NoImp) {
322f22ef01cSRoman Divacky return new (InstructionRecycler.Allocate<MachineInstr>(Allocator))
323139f7f9bSDimitry Andric MachineInstr(*this, MCID, DL, NoImp);
324f22ef01cSRoman Divacky }
325f22ef01cSRoman Divacky
3268f0fd8f6SDimitry Andric /// Create a new MachineInstr which is a copy of the 'Orig' instruction,
3278f0fd8f6SDimitry Andric /// identical in all ways except the instruction has no parent, prev, or next.
328f22ef01cSRoman Divacky MachineInstr *
CloneMachineInstr(const MachineInstr * Orig)329f22ef01cSRoman Divacky MachineFunction::CloneMachineInstr(const MachineInstr *Orig) {
330f22ef01cSRoman Divacky return new (InstructionRecycler.Allocate<MachineInstr>(Allocator))
331f22ef01cSRoman Divacky MachineInstr(*this, *Orig);
332f22ef01cSRoman Divacky }
333f22ef01cSRoman Divacky
CloneMachineInstrBundle(MachineBasicBlock & MBB,MachineBasicBlock::iterator InsertBefore,const MachineInstr & Orig)3342cab237bSDimitry Andric MachineInstr &MachineFunction::CloneMachineInstrBundle(MachineBasicBlock &MBB,
3352cab237bSDimitry Andric MachineBasicBlock::iterator InsertBefore, const MachineInstr &Orig) {
3362cab237bSDimitry Andric MachineInstr *FirstClone = nullptr;
3372cab237bSDimitry Andric MachineBasicBlock::const_instr_iterator I = Orig.getIterator();
3382cab237bSDimitry Andric while (true) {
3392cab237bSDimitry Andric MachineInstr *Cloned = CloneMachineInstr(&*I);
3402cab237bSDimitry Andric MBB.insert(InsertBefore, Cloned);
3412cab237bSDimitry Andric if (FirstClone == nullptr) {
3422cab237bSDimitry Andric FirstClone = Cloned;
3432cab237bSDimitry Andric } else {
3442cab237bSDimitry Andric Cloned->bundleWithPred();
3452cab237bSDimitry Andric }
3462cab237bSDimitry Andric
3472cab237bSDimitry Andric if (!I->isBundledWithSucc())
3482cab237bSDimitry Andric break;
3492cab237bSDimitry Andric ++I;
3502cab237bSDimitry Andric }
3512cab237bSDimitry Andric return *FirstClone;
3522cab237bSDimitry Andric }
3532cab237bSDimitry Andric
3548f0fd8f6SDimitry Andric /// Delete the given MachineInstr.
355f22ef01cSRoman Divacky ///
356139f7f9bSDimitry Andric /// This function also serves as the MachineInstr destructor - the real
357139f7f9bSDimitry Andric /// ~MachineInstr() destructor must be empty.
358f22ef01cSRoman Divacky void
DeleteMachineInstr(MachineInstr * MI)359f22ef01cSRoman Divacky MachineFunction::DeleteMachineInstr(MachineInstr *MI) {
360139f7f9bSDimitry Andric // Strip it for parts. The operand array and the MI object itself are
361139f7f9bSDimitry Andric // independently recyclable.
362139f7f9bSDimitry Andric if (MI->Operands)
363139f7f9bSDimitry Andric deallocateOperandArray(MI->CapOperands, MI->Operands);
364139f7f9bSDimitry Andric // Don't call ~MachineInstr() which must be trivial anyway because
365139f7f9bSDimitry Andric // ~MachineFunction drops whole lists of MachineInstrs wihout calling their
366139f7f9bSDimitry Andric // destructors.
367f22ef01cSRoman Divacky InstructionRecycler.Deallocate(Allocator, MI);
368f22ef01cSRoman Divacky }
369f22ef01cSRoman Divacky
3708f0fd8f6SDimitry Andric /// Allocate a new MachineBasicBlock. Use this instead of
3718f0fd8f6SDimitry Andric /// `new MachineBasicBlock'.
372f22ef01cSRoman Divacky MachineBasicBlock *
CreateMachineBasicBlock(const BasicBlock * bb)373f22ef01cSRoman Divacky MachineFunction::CreateMachineBasicBlock(const BasicBlock *bb) {
374f22ef01cSRoman Divacky return new (BasicBlockRecycler.Allocate<MachineBasicBlock>(Allocator))
375f22ef01cSRoman Divacky MachineBasicBlock(*this, bb);
376f22ef01cSRoman Divacky }
377f22ef01cSRoman Divacky
3788f0fd8f6SDimitry Andric /// Delete the given MachineBasicBlock.
379f22ef01cSRoman Divacky void
DeleteMachineBasicBlock(MachineBasicBlock * MBB)380f22ef01cSRoman Divacky MachineFunction::DeleteMachineBasicBlock(MachineBasicBlock *MBB) {
381f22ef01cSRoman Divacky assert(MBB->getParent() == this && "MBB parent mismatch!");
382f22ef01cSRoman Divacky MBB->~MachineBasicBlock();
383f22ef01cSRoman Divacky BasicBlockRecycler.Deallocate(Allocator, MBB);
384f22ef01cSRoman Divacky }
385f22ef01cSRoman Divacky
getMachineMemOperand(MachinePointerInfo PtrInfo,MachineMemOperand::Flags f,uint64_t s,unsigned base_alignment,const AAMDNodes & AAInfo,const MDNode * Ranges,SyncScope::ID SSID,AtomicOrdering Ordering,AtomicOrdering FailureOrdering)3863ca95b02SDimitry Andric MachineMemOperand *MachineFunction::getMachineMemOperand(
3873ca95b02SDimitry Andric MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, uint64_t s,
388d88c1a5aSDimitry Andric unsigned base_alignment, const AAMDNodes &AAInfo, const MDNode *Ranges,
389c4394386SDimitry Andric SyncScope::ID SSID, AtomicOrdering Ordering,
390d88c1a5aSDimitry Andric AtomicOrdering FailureOrdering) {
3913ca95b02SDimitry Andric return new (Allocator)
392d88c1a5aSDimitry Andric MachineMemOperand(PtrInfo, f, s, base_alignment, AAInfo, Ranges,
393c4394386SDimitry Andric SSID, Ordering, FailureOrdering);
394f22ef01cSRoman Divacky }
395f22ef01cSRoman Divacky
396f22ef01cSRoman Divacky MachineMemOperand *
getMachineMemOperand(const MachineMemOperand * MMO,int64_t Offset,uint64_t Size)397f22ef01cSRoman Divacky MachineFunction::getMachineMemOperand(const MachineMemOperand *MMO,
398f22ef01cSRoman Divacky int64_t Offset, uint64_t Size) {
39991bc56edSDimitry Andric if (MMO->getValue())
400f22ef01cSRoman Divacky return new (Allocator)
4012754fe60SDimitry Andric MachineMemOperand(MachinePointerInfo(MMO->getValue(),
4022754fe60SDimitry Andric MMO->getOffset()+Offset),
403d88c1a5aSDimitry Andric MMO->getFlags(), Size, MMO->getBaseAlignment(),
404c4394386SDimitry Andric AAMDNodes(), nullptr, MMO->getSyncScopeID(),
405d88c1a5aSDimitry Andric MMO->getOrdering(), MMO->getFailureOrdering());
40691bc56edSDimitry Andric return new (Allocator)
40791bc56edSDimitry Andric MachineMemOperand(MachinePointerInfo(MMO->getPseudoValue(),
40891bc56edSDimitry Andric MMO->getOffset()+Offset),
409d88c1a5aSDimitry Andric MMO->getFlags(), Size, MMO->getBaseAlignment(),
410c4394386SDimitry Andric AAMDNodes(), nullptr, MMO->getSyncScopeID(),
411d88c1a5aSDimitry Andric MMO->getOrdering(), MMO->getFailureOrdering());
412f22ef01cSRoman Divacky }
413f22ef01cSRoman Divacky
4149dc417c3SDimitry Andric MachineMemOperand *
getMachineMemOperand(const MachineMemOperand * MMO,const AAMDNodes & AAInfo)4159dc417c3SDimitry Andric MachineFunction::getMachineMemOperand(const MachineMemOperand *MMO,
4169dc417c3SDimitry Andric const AAMDNodes &AAInfo) {
4179dc417c3SDimitry Andric MachinePointerInfo MPI = MMO->getValue() ?
4189dc417c3SDimitry Andric MachinePointerInfo(MMO->getValue(), MMO->getOffset()) :
4199dc417c3SDimitry Andric MachinePointerInfo(MMO->getPseudoValue(), MMO->getOffset());
4209dc417c3SDimitry Andric
4219dc417c3SDimitry Andric return new (Allocator)
4229dc417c3SDimitry Andric MachineMemOperand(MPI, MMO->getFlags(), MMO->getSize(),
4239dc417c3SDimitry Andric MMO->getBaseAlignment(), AAInfo,
4249dc417c3SDimitry Andric MMO->getRanges(), MMO->getSyncScopeID(),
4259dc417c3SDimitry Andric MMO->getOrdering(), MMO->getFailureOrdering());
4269dc417c3SDimitry Andric }
4279dc417c3SDimitry Andric
428*b5893f02SDimitry Andric MachineInstr::ExtraInfo *
createMIExtraInfo(ArrayRef<MachineMemOperand * > MMOs,MCSymbol * PreInstrSymbol,MCSymbol * PostInstrSymbol)429*b5893f02SDimitry Andric MachineFunction::createMIExtraInfo(ArrayRef<MachineMemOperand *> MMOs,
430*b5893f02SDimitry Andric MCSymbol *PreInstrSymbol,
431*b5893f02SDimitry Andric MCSymbol *PostInstrSymbol) {
432*b5893f02SDimitry Andric return MachineInstr::ExtraInfo::create(Allocator, MMOs, PreInstrSymbol,
433*b5893f02SDimitry Andric PostInstrSymbol);
434f22ef01cSRoman Divacky }
435f22ef01cSRoman Divacky
createExternalSymbolName(StringRef Name)4367d523365SDimitry Andric const char *MachineFunction::createExternalSymbolName(StringRef Name) {
4377d523365SDimitry Andric char *Dest = Allocator.Allocate<char>(Name.size() + 1);
438*b5893f02SDimitry Andric llvm::copy(Name, Dest);
4397d523365SDimitry Andric Dest[Name.size()] = 0;
4407d523365SDimitry Andric return Dest;
4417d523365SDimitry Andric }
4427d523365SDimitry Andric
allocateRegMask()4434ba319b5SDimitry Andric uint32_t *MachineFunction::allocateRegMask() {
4444ba319b5SDimitry Andric unsigned NumRegs = getSubtarget().getRegisterInfo()->getNumRegs();
4454ba319b5SDimitry Andric unsigned Size = MachineOperand::getRegMaskSize(NumRegs);
4464ba319b5SDimitry Andric uint32_t *Mask = Allocator.Allocate<uint32_t>(Size);
4474ba319b5SDimitry Andric memset(Mask, 0, Size * sizeof(Mask[0]));
4484ba319b5SDimitry Andric return Mask;
4494ba319b5SDimitry Andric }
4504ba319b5SDimitry Andric
4513861d79fSDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const4523ca95b02SDimitry Andric LLVM_DUMP_METHOD void MachineFunction::dump() const {
453f22ef01cSRoman Divacky print(dbgs());
454f22ef01cSRoman Divacky }
4553861d79fSDimitry Andric #endif
4563861d79fSDimitry Andric
getName() const4573861d79fSDimitry Andric StringRef MachineFunction::getName() const {
4582cab237bSDimitry Andric return getFunction().getName();
4593861d79fSDimitry Andric }
460f22ef01cSRoman Divacky
print(raw_ostream & OS,const SlotIndexes * Indexes) const4613ca95b02SDimitry Andric void MachineFunction::print(raw_ostream &OS, const SlotIndexes *Indexes) const {
4623861d79fSDimitry Andric OS << "# Machine code for function " << getName() << ": ";
4633ca95b02SDimitry Andric getProperties().print(OS);
464d88c1a5aSDimitry Andric OS << '\n';
465f22ef01cSRoman Divacky
466f22ef01cSRoman Divacky // Print Frame Information
467f22ef01cSRoman Divacky FrameInfo->print(*this, OS);
468f22ef01cSRoman Divacky
469f22ef01cSRoman Divacky // Print JumpTable Information
470f22ef01cSRoman Divacky if (JumpTableInfo)
471f22ef01cSRoman Divacky JumpTableInfo->print(OS);
472f22ef01cSRoman Divacky
473f22ef01cSRoman Divacky // Print Constant Pool
474f22ef01cSRoman Divacky ConstantPool->print(OS);
475f22ef01cSRoman Divacky
47639d628a0SDimitry Andric const TargetRegisterInfo *TRI = getSubtarget().getRegisterInfo();
477f22ef01cSRoman Divacky
478f22ef01cSRoman Divacky if (RegInfo && !RegInfo->livein_empty()) {
479f22ef01cSRoman Divacky OS << "Function Live Ins: ";
480f22ef01cSRoman Divacky for (MachineRegisterInfo::livein_iterator
481f22ef01cSRoman Divacky I = RegInfo->livein_begin(), E = RegInfo->livein_end(); I != E; ++I) {
4822cab237bSDimitry Andric OS << printReg(I->first, TRI);
483f22ef01cSRoman Divacky if (I->second)
4842cab237bSDimitry Andric OS << " in " << printReg(I->second, TRI);
48591bc56edSDimitry Andric if (std::next(I) != E)
486f22ef01cSRoman Divacky OS << ", ";
487f22ef01cSRoman Divacky }
488f22ef01cSRoman Divacky OS << '\n';
489f22ef01cSRoman Divacky }
490f22ef01cSRoman Divacky
4912cab237bSDimitry Andric ModuleSlotTracker MST(getFunction().getParent());
4922cab237bSDimitry Andric MST.incorporateFunction(getFunction());
49391bc56edSDimitry Andric for (const auto &BB : *this) {
494f22ef01cSRoman Divacky OS << '\n';
4954ba319b5SDimitry Andric // If we print the whole function, print it at its most verbose level.
4964ba319b5SDimitry Andric BB.print(OS, MST, Indexes, /*IsStandalone=*/true);
497f22ef01cSRoman Divacky }
498f22ef01cSRoman Divacky
4993861d79fSDimitry Andric OS << "\n# End machine code for function " << getName() << ".\n\n";
500f22ef01cSRoman Divacky }
501f22ef01cSRoman Divacky
502f22ef01cSRoman Divacky namespace llvm {
5032cab237bSDimitry Andric
504f22ef01cSRoman Divacky template<>
505f22ef01cSRoman Divacky struct DOTGraphTraits<const MachineFunction*> : public DefaultDOTGraphTraits {
DOTGraphTraitsllvm::DOTGraphTraits506f22ef01cSRoman Divacky DOTGraphTraits(bool isSimple = false) : DefaultDOTGraphTraits(isSimple) {}
507f22ef01cSRoman Divacky
getGraphNamellvm::DOTGraphTraits508f22ef01cSRoman Divacky static std::string getGraphName(const MachineFunction *F) {
509ff0cc061SDimitry Andric return ("CFG for '" + F->getName() + "' function").str();
510f22ef01cSRoman Divacky }
511f22ef01cSRoman Divacky
getNodeLabelllvm::DOTGraphTraits512f22ef01cSRoman Divacky std::string getNodeLabel(const MachineBasicBlock *Node,
513f22ef01cSRoman Divacky const MachineFunction *Graph) {
514f22ef01cSRoman Divacky std::string OutStr;
515f22ef01cSRoman Divacky {
516f22ef01cSRoman Divacky raw_string_ostream OSS(OutStr);
517f22ef01cSRoman Divacky
5182754fe60SDimitry Andric if (isSimple()) {
5192cab237bSDimitry Andric OSS << printMBBReference(*Node);
5202754fe60SDimitry Andric if (const BasicBlock *BB = Node->getBasicBlock())
5212754fe60SDimitry Andric OSS << ": " << BB->getName();
5222754fe60SDimitry Andric } else
523f22ef01cSRoman Divacky Node->print(OSS);
524f22ef01cSRoman Divacky }
525f22ef01cSRoman Divacky
526f22ef01cSRoman Divacky if (OutStr[0] == '\n') OutStr.erase(OutStr.begin());
527f22ef01cSRoman Divacky
528f22ef01cSRoman Divacky // Process string output to make it nicer...
529f22ef01cSRoman Divacky for (unsigned i = 0; i != OutStr.length(); ++i)
530f22ef01cSRoman Divacky if (OutStr[i] == '\n') { // Left justify
531f22ef01cSRoman Divacky OutStr[i] = '\\';
532f22ef01cSRoman Divacky OutStr.insert(OutStr.begin()+i+1, 'l');
533f22ef01cSRoman Divacky }
534f22ef01cSRoman Divacky return OutStr;
535f22ef01cSRoman Divacky }
536f22ef01cSRoman Divacky };
5372cab237bSDimitry Andric
5382cab237bSDimitry Andric } // end namespace llvm
539f22ef01cSRoman Divacky
viewCFG() const540f22ef01cSRoman Divacky void MachineFunction::viewCFG() const
541f22ef01cSRoman Divacky {
542f22ef01cSRoman Divacky #ifndef NDEBUG
5433861d79fSDimitry Andric ViewGraph(this, "mf" + getName());
544f22ef01cSRoman Divacky #else
545ffd1746dSEd Schouten errs() << "MachineFunction::viewCFG is only available in debug builds on "
546f22ef01cSRoman Divacky << "systems with Graphviz or gv!\n";
547f22ef01cSRoman Divacky #endif // NDEBUG
548f22ef01cSRoman Divacky }
549f22ef01cSRoman Divacky
viewCFGOnly() const550f22ef01cSRoman Divacky void MachineFunction::viewCFGOnly() const
551f22ef01cSRoman Divacky {
552f22ef01cSRoman Divacky #ifndef NDEBUG
5533861d79fSDimitry Andric ViewGraph(this, "mf" + getName(), true);
554f22ef01cSRoman Divacky #else
555ffd1746dSEd Schouten errs() << "MachineFunction::viewCFGOnly is only available in debug builds on "
556f22ef01cSRoman Divacky << "systems with Graphviz or gv!\n";
557f22ef01cSRoman Divacky #endif // NDEBUG
558f22ef01cSRoman Divacky }
559f22ef01cSRoman Divacky
5608f0fd8f6SDimitry Andric /// Add the specified physical register as a live-in value and
561f22ef01cSRoman Divacky /// create a corresponding virtual register for it.
addLiveIn(unsigned PReg,const TargetRegisterClass * RC)562f22ef01cSRoman Divacky unsigned MachineFunction::addLiveIn(unsigned PReg,
563dd6029ffSDimitry Andric const TargetRegisterClass *RC) {
564f22ef01cSRoman Divacky MachineRegisterInfo &MRI = getRegInfo();
565f22ef01cSRoman Divacky unsigned VReg = MRI.getLiveInVirtReg(PReg);
566f22ef01cSRoman Divacky if (VReg) {
56791bc56edSDimitry Andric const TargetRegisterClass *VRegRC = MRI.getRegClass(VReg);
56891bc56edSDimitry Andric (void)VRegRC;
56991bc56edSDimitry Andric // A physical register can be added several times.
57091bc56edSDimitry Andric // Between two calls, the register class of the related virtual register
57191bc56edSDimitry Andric // may have been constrained to match some operation constraints.
57291bc56edSDimitry Andric // In that case, check that the current register class includes the
57391bc56edSDimitry Andric // physical register and is a sub class of the specified RC.
57491bc56edSDimitry Andric assert((VRegRC == RC || (VRegRC->contains(PReg) &&
57591bc56edSDimitry Andric RC->hasSubClassEq(VRegRC))) &&
57691bc56edSDimitry Andric "Register class mismatch!");
577f22ef01cSRoman Divacky return VReg;
578f22ef01cSRoman Divacky }
579f22ef01cSRoman Divacky VReg = MRI.createVirtualRegister(RC);
580f22ef01cSRoman Divacky MRI.addLiveIn(PReg, VReg);
581f22ef01cSRoman Divacky return VReg;
582f22ef01cSRoman Divacky }
583f22ef01cSRoman Divacky
5848f0fd8f6SDimitry Andric /// Return the MCSymbol for the specified non-empty jump table.
585f22ef01cSRoman Divacky /// If isLinkerPrivate is specified, an 'l' label is returned, otherwise a
586f22ef01cSRoman Divacky /// normal 'L' label is returned.
getJTISymbol(unsigned JTI,MCContext & Ctx,bool isLinkerPrivate) const587f22ef01cSRoman Divacky MCSymbol *MachineFunction::getJTISymbol(unsigned JTI, MCContext &Ctx,
588f22ef01cSRoman Divacky bool isLinkerPrivate) const {
589875ed548SDimitry Andric const DataLayout &DL = getDataLayout();
590f22ef01cSRoman Divacky assert(JumpTableInfo && "No jump tables");
591f22ef01cSRoman Divacky assert(JTI < JumpTableInfo->getJumpTables().size() && "Invalid JTI!");
592f22ef01cSRoman Divacky
593d88c1a5aSDimitry Andric StringRef Prefix = isLinkerPrivate ? DL.getLinkerPrivateGlobalPrefix()
594875ed548SDimitry Andric : DL.getPrivateGlobalPrefix();
595f22ef01cSRoman Divacky SmallString<60> Name;
596f22ef01cSRoman Divacky raw_svector_ostream(Name)
597f22ef01cSRoman Divacky << Prefix << "JTI" << getFunctionNumber() << '_' << JTI;
598ff0cc061SDimitry Andric return Ctx.getOrCreateSymbol(Name);
599f22ef01cSRoman Divacky }
600f22ef01cSRoman Divacky
6018f0fd8f6SDimitry Andric /// Return a function-local symbol to represent the PIC base.
getPICBaseSymbol() const6022754fe60SDimitry Andric MCSymbol *MachineFunction::getPICBaseSymbol() const {
603875ed548SDimitry Andric const DataLayout &DL = getDataLayout();
604875ed548SDimitry Andric return Ctx.getOrCreateSymbol(Twine(DL.getPrivateGlobalPrefix()) +
6052754fe60SDimitry Andric Twine(getFunctionNumber()) + "$pb");
6062754fe60SDimitry Andric }
607f22ef01cSRoman Divacky
608d88c1a5aSDimitry Andric /// \name Exception Handling
609d88c1a5aSDimitry Andric /// \{
610d88c1a5aSDimitry Andric
611d88c1a5aSDimitry Andric LandingPadInfo &
getOrCreateLandingPadInfo(MachineBasicBlock * LandingPad)612d88c1a5aSDimitry Andric MachineFunction::getOrCreateLandingPadInfo(MachineBasicBlock *LandingPad) {
613d88c1a5aSDimitry Andric unsigned N = LandingPads.size();
614d88c1a5aSDimitry Andric for (unsigned i = 0; i < N; ++i) {
615d88c1a5aSDimitry Andric LandingPadInfo &LP = LandingPads[i];
616d88c1a5aSDimitry Andric if (LP.LandingPadBlock == LandingPad)
617d88c1a5aSDimitry Andric return LP;
618d88c1a5aSDimitry Andric }
619d88c1a5aSDimitry Andric
620d88c1a5aSDimitry Andric LandingPads.push_back(LandingPadInfo(LandingPad));
621d88c1a5aSDimitry Andric return LandingPads[N];
622d88c1a5aSDimitry Andric }
623d88c1a5aSDimitry Andric
addInvoke(MachineBasicBlock * LandingPad,MCSymbol * BeginLabel,MCSymbol * EndLabel)624d88c1a5aSDimitry Andric void MachineFunction::addInvoke(MachineBasicBlock *LandingPad,
625d88c1a5aSDimitry Andric MCSymbol *BeginLabel, MCSymbol *EndLabel) {
626d88c1a5aSDimitry Andric LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
627d88c1a5aSDimitry Andric LP.BeginLabels.push_back(BeginLabel);
628d88c1a5aSDimitry Andric LP.EndLabels.push_back(EndLabel);
629d88c1a5aSDimitry Andric }
630d88c1a5aSDimitry Andric
addLandingPad(MachineBasicBlock * LandingPad)631d88c1a5aSDimitry Andric MCSymbol *MachineFunction::addLandingPad(MachineBasicBlock *LandingPad) {
632d88c1a5aSDimitry Andric MCSymbol *LandingPadLabel = Ctx.createTempSymbol();
633d88c1a5aSDimitry Andric LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
634d88c1a5aSDimitry Andric LP.LandingPadLabel = LandingPadLabel;
635*b5893f02SDimitry Andric
636*b5893f02SDimitry Andric const Instruction *FirstI = LandingPad->getBasicBlock()->getFirstNonPHI();
637*b5893f02SDimitry Andric if (const auto *LPI = dyn_cast<LandingPadInst>(FirstI)) {
638*b5893f02SDimitry Andric if (const auto *PF =
639*b5893f02SDimitry Andric dyn_cast<Function>(F.getPersonalityFn()->stripPointerCasts()))
640*b5893f02SDimitry Andric getMMI().addPersonality(PF);
641*b5893f02SDimitry Andric
642*b5893f02SDimitry Andric if (LPI->isCleanup())
643*b5893f02SDimitry Andric addCleanup(LandingPad);
644*b5893f02SDimitry Andric
645*b5893f02SDimitry Andric // FIXME: New EH - Add the clauses in reverse order. This isn't 100%
646*b5893f02SDimitry Andric // correct, but we need to do it this way because of how the DWARF EH
647*b5893f02SDimitry Andric // emitter processes the clauses.
648*b5893f02SDimitry Andric for (unsigned I = LPI->getNumClauses(); I != 0; --I) {
649*b5893f02SDimitry Andric Value *Val = LPI->getClause(I - 1);
650*b5893f02SDimitry Andric if (LPI->isCatch(I - 1)) {
651*b5893f02SDimitry Andric addCatchTypeInfo(LandingPad,
652*b5893f02SDimitry Andric dyn_cast<GlobalValue>(Val->stripPointerCasts()));
653*b5893f02SDimitry Andric } else {
654*b5893f02SDimitry Andric // Add filters in a list.
655*b5893f02SDimitry Andric auto *CVal = cast<Constant>(Val);
656*b5893f02SDimitry Andric SmallVector<const GlobalValue *, 4> FilterList;
657*b5893f02SDimitry Andric for (User::op_iterator II = CVal->op_begin(), IE = CVal->op_end();
658*b5893f02SDimitry Andric II != IE; ++II)
659*b5893f02SDimitry Andric FilterList.push_back(cast<GlobalValue>((*II)->stripPointerCasts()));
660*b5893f02SDimitry Andric
661*b5893f02SDimitry Andric addFilterTypeInfo(LandingPad, FilterList);
662*b5893f02SDimitry Andric }
663*b5893f02SDimitry Andric }
664*b5893f02SDimitry Andric
665*b5893f02SDimitry Andric } else if (const auto *CPI = dyn_cast<CatchPadInst>(FirstI)) {
666*b5893f02SDimitry Andric for (unsigned I = CPI->getNumArgOperands(); I != 0; --I) {
667*b5893f02SDimitry Andric Value *TypeInfo = CPI->getArgOperand(I - 1)->stripPointerCasts();
668*b5893f02SDimitry Andric addCatchTypeInfo(LandingPad, dyn_cast<GlobalValue>(TypeInfo));
669*b5893f02SDimitry Andric }
670*b5893f02SDimitry Andric
671*b5893f02SDimitry Andric } else {
672*b5893f02SDimitry Andric assert(isa<CleanupPadInst>(FirstI) && "Invalid landingpad!");
673*b5893f02SDimitry Andric }
674*b5893f02SDimitry Andric
675d88c1a5aSDimitry Andric return LandingPadLabel;
676d88c1a5aSDimitry Andric }
677d88c1a5aSDimitry Andric
addCatchTypeInfo(MachineBasicBlock * LandingPad,ArrayRef<const GlobalValue * > TyInfo)678d88c1a5aSDimitry Andric void MachineFunction::addCatchTypeInfo(MachineBasicBlock *LandingPad,
679d88c1a5aSDimitry Andric ArrayRef<const GlobalValue *> TyInfo) {
680d88c1a5aSDimitry Andric LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
681d88c1a5aSDimitry Andric for (unsigned N = TyInfo.size(); N; --N)
682d88c1a5aSDimitry Andric LP.TypeIds.push_back(getTypeIDFor(TyInfo[N - 1]));
683d88c1a5aSDimitry Andric }
684d88c1a5aSDimitry Andric
addFilterTypeInfo(MachineBasicBlock * LandingPad,ArrayRef<const GlobalValue * > TyInfo)685d88c1a5aSDimitry Andric void MachineFunction::addFilterTypeInfo(MachineBasicBlock *LandingPad,
686d88c1a5aSDimitry Andric ArrayRef<const GlobalValue *> TyInfo) {
687d88c1a5aSDimitry Andric LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
688d88c1a5aSDimitry Andric std::vector<unsigned> IdsInFilter(TyInfo.size());
689d88c1a5aSDimitry Andric for (unsigned I = 0, E = TyInfo.size(); I != E; ++I)
690d88c1a5aSDimitry Andric IdsInFilter[I] = getTypeIDFor(TyInfo[I]);
691d88c1a5aSDimitry Andric LP.TypeIds.push_back(getFilterIDFor(IdsInFilter));
692d88c1a5aSDimitry Andric }
693d88c1a5aSDimitry Andric
tidyLandingPads(DenseMap<MCSymbol *,uintptr_t> * LPMap,bool TidyIfNoBeginLabels)694*b5893f02SDimitry Andric void MachineFunction::tidyLandingPads(DenseMap<MCSymbol *, uintptr_t> *LPMap,
695*b5893f02SDimitry Andric bool TidyIfNoBeginLabels) {
696d88c1a5aSDimitry Andric for (unsigned i = 0; i != LandingPads.size(); ) {
697d88c1a5aSDimitry Andric LandingPadInfo &LandingPad = LandingPads[i];
698d88c1a5aSDimitry Andric if (LandingPad.LandingPadLabel &&
699d88c1a5aSDimitry Andric !LandingPad.LandingPadLabel->isDefined() &&
700d88c1a5aSDimitry Andric (!LPMap || (*LPMap)[LandingPad.LandingPadLabel] == 0))
701d88c1a5aSDimitry Andric LandingPad.LandingPadLabel = nullptr;
702d88c1a5aSDimitry Andric
703d88c1a5aSDimitry Andric // Special case: we *should* emit LPs with null LP MBB. This indicates
704d88c1a5aSDimitry Andric // "nounwind" case.
705d88c1a5aSDimitry Andric if (!LandingPad.LandingPadLabel && LandingPad.LandingPadBlock) {
706d88c1a5aSDimitry Andric LandingPads.erase(LandingPads.begin() + i);
707d88c1a5aSDimitry Andric continue;
708d88c1a5aSDimitry Andric }
709d88c1a5aSDimitry Andric
710*b5893f02SDimitry Andric if (TidyIfNoBeginLabels) {
711d88c1a5aSDimitry Andric for (unsigned j = 0, e = LandingPads[i].BeginLabels.size(); j != e; ++j) {
712d88c1a5aSDimitry Andric MCSymbol *BeginLabel = LandingPad.BeginLabels[j];
713d88c1a5aSDimitry Andric MCSymbol *EndLabel = LandingPad.EndLabels[j];
714*b5893f02SDimitry Andric if ((BeginLabel->isDefined() || (LPMap && (*LPMap)[BeginLabel] != 0)) &&
715*b5893f02SDimitry Andric (EndLabel->isDefined() || (LPMap && (*LPMap)[EndLabel] != 0)))
716*b5893f02SDimitry Andric continue;
717d88c1a5aSDimitry Andric
718d88c1a5aSDimitry Andric LandingPad.BeginLabels.erase(LandingPad.BeginLabels.begin() + j);
719d88c1a5aSDimitry Andric LandingPad.EndLabels.erase(LandingPad.EndLabels.begin() + j);
720d88c1a5aSDimitry Andric --j;
721d88c1a5aSDimitry Andric --e;
722d88c1a5aSDimitry Andric }
723d88c1a5aSDimitry Andric
724d88c1a5aSDimitry Andric // Remove landing pads with no try-ranges.
725d88c1a5aSDimitry Andric if (LandingPads[i].BeginLabels.empty()) {
726d88c1a5aSDimitry Andric LandingPads.erase(LandingPads.begin() + i);
727d88c1a5aSDimitry Andric continue;
728d88c1a5aSDimitry Andric }
729*b5893f02SDimitry Andric }
730d88c1a5aSDimitry Andric
731d88c1a5aSDimitry Andric // If there is no landing pad, ensure that the list of typeids is empty.
732d88c1a5aSDimitry Andric // If the only typeid is a cleanup, this is the same as having no typeids.
733d88c1a5aSDimitry Andric if (!LandingPad.LandingPadBlock ||
734d88c1a5aSDimitry Andric (LandingPad.TypeIds.size() == 1 && !LandingPad.TypeIds[0]))
735d88c1a5aSDimitry Andric LandingPad.TypeIds.clear();
736d88c1a5aSDimitry Andric ++i;
737d88c1a5aSDimitry Andric }
738d88c1a5aSDimitry Andric }
739d88c1a5aSDimitry Andric
addCleanup(MachineBasicBlock * LandingPad)740d88c1a5aSDimitry Andric void MachineFunction::addCleanup(MachineBasicBlock *LandingPad) {
741d88c1a5aSDimitry Andric LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
742d88c1a5aSDimitry Andric LP.TypeIds.push_back(0);
743d88c1a5aSDimitry Andric }
744d88c1a5aSDimitry Andric
addSEHCatchHandler(MachineBasicBlock * LandingPad,const Function * Filter,const BlockAddress * RecoverBA)745d88c1a5aSDimitry Andric void MachineFunction::addSEHCatchHandler(MachineBasicBlock *LandingPad,
746d88c1a5aSDimitry Andric const Function *Filter,
747d88c1a5aSDimitry Andric const BlockAddress *RecoverBA) {
748d88c1a5aSDimitry Andric LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
749d88c1a5aSDimitry Andric SEHHandler Handler;
750d88c1a5aSDimitry Andric Handler.FilterOrFinally = Filter;
751d88c1a5aSDimitry Andric Handler.RecoverBA = RecoverBA;
752d88c1a5aSDimitry Andric LP.SEHHandlers.push_back(Handler);
753d88c1a5aSDimitry Andric }
754d88c1a5aSDimitry Andric
addSEHCleanupHandler(MachineBasicBlock * LandingPad,const Function * Cleanup)755d88c1a5aSDimitry Andric void MachineFunction::addSEHCleanupHandler(MachineBasicBlock *LandingPad,
756d88c1a5aSDimitry Andric const Function *Cleanup) {
757d88c1a5aSDimitry Andric LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
758d88c1a5aSDimitry Andric SEHHandler Handler;
759d88c1a5aSDimitry Andric Handler.FilterOrFinally = Cleanup;
760d88c1a5aSDimitry Andric Handler.RecoverBA = nullptr;
761d88c1a5aSDimitry Andric LP.SEHHandlers.push_back(Handler);
762d88c1a5aSDimitry Andric }
763d88c1a5aSDimitry Andric
setCallSiteLandingPad(MCSymbol * Sym,ArrayRef<unsigned> Sites)764d88c1a5aSDimitry Andric void MachineFunction::setCallSiteLandingPad(MCSymbol *Sym,
765d88c1a5aSDimitry Andric ArrayRef<unsigned> Sites) {
766d88c1a5aSDimitry Andric LPadToCallSiteMap[Sym].append(Sites.begin(), Sites.end());
767d88c1a5aSDimitry Andric }
768d88c1a5aSDimitry Andric
getTypeIDFor(const GlobalValue * TI)769d88c1a5aSDimitry Andric unsigned MachineFunction::getTypeIDFor(const GlobalValue *TI) {
770d88c1a5aSDimitry Andric for (unsigned i = 0, N = TypeInfos.size(); i != N; ++i)
771d88c1a5aSDimitry Andric if (TypeInfos[i] == TI) return i + 1;
772d88c1a5aSDimitry Andric
773d88c1a5aSDimitry Andric TypeInfos.push_back(TI);
774d88c1a5aSDimitry Andric return TypeInfos.size();
775d88c1a5aSDimitry Andric }
776d88c1a5aSDimitry Andric
getFilterIDFor(std::vector<unsigned> & TyIds)777d88c1a5aSDimitry Andric int MachineFunction::getFilterIDFor(std::vector<unsigned> &TyIds) {
778d88c1a5aSDimitry Andric // If the new filter coincides with the tail of an existing filter, then
779d88c1a5aSDimitry Andric // re-use the existing filter. Folding filters more than this requires
780d88c1a5aSDimitry Andric // re-ordering filters and/or their elements - probably not worth it.
781d88c1a5aSDimitry Andric for (std::vector<unsigned>::iterator I = FilterEnds.begin(),
782d88c1a5aSDimitry Andric E = FilterEnds.end(); I != E; ++I) {
783d88c1a5aSDimitry Andric unsigned i = *I, j = TyIds.size();
784d88c1a5aSDimitry Andric
785d88c1a5aSDimitry Andric while (i && j)
786d88c1a5aSDimitry Andric if (FilterIds[--i] != TyIds[--j])
787d88c1a5aSDimitry Andric goto try_next;
788d88c1a5aSDimitry Andric
789d88c1a5aSDimitry Andric if (!j)
790d88c1a5aSDimitry Andric // The new filter coincides with range [i, end) of the existing filter.
791d88c1a5aSDimitry Andric return -(1 + i);
792d88c1a5aSDimitry Andric
793d88c1a5aSDimitry Andric try_next:;
794d88c1a5aSDimitry Andric }
795d88c1a5aSDimitry Andric
796d88c1a5aSDimitry Andric // Add the new filter.
797d88c1a5aSDimitry Andric int FilterID = -(1 + FilterIds.size());
798d88c1a5aSDimitry Andric FilterIds.reserve(FilterIds.size() + TyIds.size() + 1);
799d88c1a5aSDimitry Andric FilterIds.insert(FilterIds.end(), TyIds.begin(), TyIds.end());
800d88c1a5aSDimitry Andric FilterEnds.push_back(FilterIds.size());
801d88c1a5aSDimitry Andric FilterIds.push_back(0); // terminator
802d88c1a5aSDimitry Andric return FilterID;
803d88c1a5aSDimitry Andric }
804d88c1a5aSDimitry Andric
805d88c1a5aSDimitry Andric /// \}
806d88c1a5aSDimitry Andric
807f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
808f22ef01cSRoman Divacky // MachineJumpTableInfo implementation
809f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
810f22ef01cSRoman Divacky
8118f0fd8f6SDimitry Andric /// Return the size of each entry in the jump table.
getEntrySize(const DataLayout & TD) const8123861d79fSDimitry Andric unsigned MachineJumpTableInfo::getEntrySize(const DataLayout &TD) const {
813f22ef01cSRoman Divacky // The size of a jump table entry is 4 bytes unless the entry is just the
814f22ef01cSRoman Divacky // address of a block, in which case it is the pointer size.
815f22ef01cSRoman Divacky switch (getEntryKind()) {
816f22ef01cSRoman Divacky case MachineJumpTableInfo::EK_BlockAddress:
817f22ef01cSRoman Divacky return TD.getPointerSize();
818dff0c46cSDimitry Andric case MachineJumpTableInfo::EK_GPRel64BlockAddress:
819dff0c46cSDimitry Andric return 8;
820f22ef01cSRoman Divacky case MachineJumpTableInfo::EK_GPRel32BlockAddress:
821f22ef01cSRoman Divacky case MachineJumpTableInfo::EK_LabelDifference32:
822f22ef01cSRoman Divacky case MachineJumpTableInfo::EK_Custom32:
823f22ef01cSRoman Divacky return 4;
824f22ef01cSRoman Divacky case MachineJumpTableInfo::EK_Inline:
825f22ef01cSRoman Divacky return 0;
826f22ef01cSRoman Divacky }
827dff0c46cSDimitry Andric llvm_unreachable("Unknown jump table encoding!");
828f22ef01cSRoman Divacky }
829f22ef01cSRoman Divacky
8308f0fd8f6SDimitry Andric /// Return the alignment of each entry in the jump table.
getEntryAlignment(const DataLayout & TD) const8313861d79fSDimitry Andric unsigned MachineJumpTableInfo::getEntryAlignment(const DataLayout &TD) const {
832f22ef01cSRoman Divacky // The alignment of a jump table entry is the alignment of int32 unless the
833f22ef01cSRoman Divacky // entry is just the address of a block, in which case it is the pointer
834f22ef01cSRoman Divacky // alignment.
835f22ef01cSRoman Divacky switch (getEntryKind()) {
836f22ef01cSRoman Divacky case MachineJumpTableInfo::EK_BlockAddress:
8372cab237bSDimitry Andric return TD.getPointerABIAlignment(0);
838dff0c46cSDimitry Andric case MachineJumpTableInfo::EK_GPRel64BlockAddress:
839dff0c46cSDimitry Andric return TD.getABIIntegerTypeAlignment(64);
840f22ef01cSRoman Divacky case MachineJumpTableInfo::EK_GPRel32BlockAddress:
841f22ef01cSRoman Divacky case MachineJumpTableInfo::EK_LabelDifference32:
842f22ef01cSRoman Divacky case MachineJumpTableInfo::EK_Custom32:
843f22ef01cSRoman Divacky return TD.getABIIntegerTypeAlignment(32);
844f22ef01cSRoman Divacky case MachineJumpTableInfo::EK_Inline:
845f22ef01cSRoman Divacky return 1;
846f22ef01cSRoman Divacky }
847dff0c46cSDimitry Andric llvm_unreachable("Unknown jump table encoding!");
848f22ef01cSRoman Divacky }
849f22ef01cSRoman Divacky
8508f0fd8f6SDimitry Andric /// Create a new jump table entry in the jump table info.
createJumpTableIndex(const std::vector<MachineBasicBlock * > & DestBBs)851f22ef01cSRoman Divacky unsigned MachineJumpTableInfo::createJumpTableIndex(
852f22ef01cSRoman Divacky const std::vector<MachineBasicBlock*> &DestBBs) {
853f22ef01cSRoman Divacky assert(!DestBBs.empty() && "Cannot create an empty jump table!");
854f22ef01cSRoman Divacky JumpTables.push_back(MachineJumpTableEntry(DestBBs));
855f22ef01cSRoman Divacky return JumpTables.size()-1;
856f22ef01cSRoman Divacky }
857f22ef01cSRoman Divacky
8588f0fd8f6SDimitry Andric /// If Old is the target of any jump tables, update the jump tables to branch
8598f0fd8f6SDimitry Andric /// to New instead.
ReplaceMBBInJumpTables(MachineBasicBlock * Old,MachineBasicBlock * New)860f22ef01cSRoman Divacky bool MachineJumpTableInfo::ReplaceMBBInJumpTables(MachineBasicBlock *Old,
861f22ef01cSRoman Divacky MachineBasicBlock *New) {
862f22ef01cSRoman Divacky assert(Old != New && "Not making a change?");
863f22ef01cSRoman Divacky bool MadeChange = false;
864f22ef01cSRoman Divacky for (size_t i = 0, e = JumpTables.size(); i != e; ++i)
865f22ef01cSRoman Divacky ReplaceMBBInJumpTable(i, Old, New);
866f22ef01cSRoman Divacky return MadeChange;
867f22ef01cSRoman Divacky }
868f22ef01cSRoman Divacky
8698f0fd8f6SDimitry Andric /// If Old is a target of the jump tables, update the jump table to branch to
8708f0fd8f6SDimitry Andric /// New instead.
ReplaceMBBInJumpTable(unsigned Idx,MachineBasicBlock * Old,MachineBasicBlock * New)871f22ef01cSRoman Divacky bool MachineJumpTableInfo::ReplaceMBBInJumpTable(unsigned Idx,
872f22ef01cSRoman Divacky MachineBasicBlock *Old,
873f22ef01cSRoman Divacky MachineBasicBlock *New) {
874f22ef01cSRoman Divacky assert(Old != New && "Not making a change?");
875f22ef01cSRoman Divacky bool MadeChange = false;
876f22ef01cSRoman Divacky MachineJumpTableEntry &JTE = JumpTables[Idx];
877f22ef01cSRoman Divacky for (size_t j = 0, e = JTE.MBBs.size(); j != e; ++j)
878f22ef01cSRoman Divacky if (JTE.MBBs[j] == Old) {
879f22ef01cSRoman Divacky JTE.MBBs[j] = New;
880f22ef01cSRoman Divacky MadeChange = true;
881f22ef01cSRoman Divacky }
882f22ef01cSRoman Divacky return MadeChange;
883f22ef01cSRoman Divacky }
884f22ef01cSRoman Divacky
print(raw_ostream & OS) const885f22ef01cSRoman Divacky void MachineJumpTableInfo::print(raw_ostream &OS) const {
886f22ef01cSRoman Divacky if (JumpTables.empty()) return;
887f22ef01cSRoman Divacky
888f22ef01cSRoman Divacky OS << "Jump Tables:\n";
889f22ef01cSRoman Divacky
890f22ef01cSRoman Divacky for (unsigned i = 0, e = JumpTables.size(); i != e; ++i) {
8912cab237bSDimitry Andric OS << printJumpTableEntryReference(i) << ": ";
892f22ef01cSRoman Divacky for (unsigned j = 0, f = JumpTables[i].MBBs.size(); j != f; ++j)
8932cab237bSDimitry Andric OS << ' ' << printMBBReference(*JumpTables[i].MBBs[j]);
894f22ef01cSRoman Divacky }
895f22ef01cSRoman Divacky
896f22ef01cSRoman Divacky OS << '\n';
897f22ef01cSRoman Divacky }
898f22ef01cSRoman Divacky
8993861d79fSDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const9003ca95b02SDimitry Andric LLVM_DUMP_METHOD void MachineJumpTableInfo::dump() const { print(dbgs()); }
9013861d79fSDimitry Andric #endif
902f22ef01cSRoman Divacky
printJumpTableEntryReference(unsigned Idx)9032cab237bSDimitry Andric Printable llvm::printJumpTableEntryReference(unsigned Idx) {
9042cab237bSDimitry Andric return Printable([Idx](raw_ostream &OS) { OS << "%jump-table." << Idx; });
9052cab237bSDimitry Andric }
906f22ef01cSRoman Divacky
907f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
908f22ef01cSRoman Divacky // MachineConstantPool implementation
909f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
910f22ef01cSRoman Divacky
anchor()911dff0c46cSDimitry Andric void MachineConstantPoolValue::anchor() {}
912dff0c46cSDimitry Andric
getType() const9136122f3e6SDimitry Andric Type *MachineConstantPoolEntry::getType() const {
914f22ef01cSRoman Divacky if (isMachineConstantPoolEntry())
915f22ef01cSRoman Divacky return Val.MachineCPVal->getType();
916f22ef01cSRoman Divacky return Val.ConstVal->getType();
917f22ef01cSRoman Divacky }
918f22ef01cSRoman Divacky
needsRelocation() const9197d523365SDimitry Andric bool MachineConstantPoolEntry::needsRelocation() const {
920f22ef01cSRoman Divacky if (isMachineConstantPoolEntry())
9217d523365SDimitry Andric return true;
9227d523365SDimitry Andric return Val.ConstVal->needsRelocation();
923f22ef01cSRoman Divacky }
924f22ef01cSRoman Divacky
92591bc56edSDimitry Andric SectionKind
getSectionKind(const DataLayout * DL) const92691bc56edSDimitry Andric MachineConstantPoolEntry::getSectionKind(const DataLayout *DL) const {
9277d523365SDimitry Andric if (needsRelocation())
9287d523365SDimitry Andric return SectionKind::getReadOnlyWithRel();
92991bc56edSDimitry Andric switch (DL->getTypeAllocSize(getType())) {
93091bc56edSDimitry Andric case 4:
9317d523365SDimitry Andric return SectionKind::getMergeableConst4();
93291bc56edSDimitry Andric case 8:
9337d523365SDimitry Andric return SectionKind::getMergeableConst8();
93491bc56edSDimitry Andric case 16:
9357d523365SDimitry Andric return SectionKind::getMergeableConst16();
9363ca95b02SDimitry Andric case 32:
9373ca95b02SDimitry Andric return SectionKind::getMergeableConst32();
93891bc56edSDimitry Andric default:
9397d523365SDimitry Andric return SectionKind::getReadOnly();
94091bc56edSDimitry Andric }
94191bc56edSDimitry Andric }
94291bc56edSDimitry Andric
~MachineConstantPool()943f22ef01cSRoman Divacky MachineConstantPool::~MachineConstantPool() {
944d88c1a5aSDimitry Andric // A constant may be a member of both Constants and MachineCPVsSharingEntries,
945d88c1a5aSDimitry Andric // so keep track of which we've deleted to avoid double deletions.
946d88c1a5aSDimitry Andric DenseSet<MachineConstantPoolValue*> Deleted;
947f22ef01cSRoman Divacky for (unsigned i = 0, e = Constants.size(); i != e; ++i)
948d88c1a5aSDimitry Andric if (Constants[i].isMachineConstantPoolEntry()) {
949d88c1a5aSDimitry Andric Deleted.insert(Constants[i].Val.MachineCPVal);
950f22ef01cSRoman Divacky delete Constants[i].Val.MachineCPVal;
951d88c1a5aSDimitry Andric }
952dd6029ffSDimitry Andric for (DenseSet<MachineConstantPoolValue*>::iterator I =
953dd6029ffSDimitry Andric MachineCPVsSharingEntries.begin(), E = MachineCPVsSharingEntries.end();
954d88c1a5aSDimitry Andric I != E; ++I) {
955d88c1a5aSDimitry Andric if (Deleted.count(*I) == 0)
956dd6029ffSDimitry Andric delete *I;
957f22ef01cSRoman Divacky }
958d88c1a5aSDimitry Andric }
959f22ef01cSRoman Divacky
9608f0fd8f6SDimitry Andric /// Test whether the given two constants can be allocated the same constant pool
9618f0fd8f6SDimitry Andric /// entry.
CanShareConstantPoolEntry(const Constant * A,const Constant * B,const DataLayout & DL)962f22ef01cSRoman Divacky static bool CanShareConstantPoolEntry(const Constant *A, const Constant *B,
963875ed548SDimitry Andric const DataLayout &DL) {
964f22ef01cSRoman Divacky // Handle the trivial case quickly.
965f22ef01cSRoman Divacky if (A == B) return true;
966f22ef01cSRoman Divacky
967f22ef01cSRoman Divacky // If they have the same type but weren't the same constant, quickly
968f22ef01cSRoman Divacky // reject them.
969f22ef01cSRoman Divacky if (A->getType() == B->getType()) return false;
970f22ef01cSRoman Divacky
971dff0c46cSDimitry Andric // We can't handle structs or arrays.
972dff0c46cSDimitry Andric if (isa<StructType>(A->getType()) || isa<ArrayType>(A->getType()) ||
973dff0c46cSDimitry Andric isa<StructType>(B->getType()) || isa<ArrayType>(B->getType()))
974dff0c46cSDimitry Andric return false;
975dff0c46cSDimitry Andric
976f22ef01cSRoman Divacky // For now, only support constants with the same size.
977875ed548SDimitry Andric uint64_t StoreSize = DL.getTypeStoreSize(A->getType());
978875ed548SDimitry Andric if (StoreSize != DL.getTypeStoreSize(B->getType()) || StoreSize > 128)
979f22ef01cSRoman Divacky return false;
980f22ef01cSRoman Divacky
981dff0c46cSDimitry Andric Type *IntTy = IntegerType::get(A->getContext(), StoreSize*8);
982f22ef01cSRoman Divacky
983dff0c46cSDimitry Andric // Try constant folding a bitcast of both instructions to an integer. If we
984dff0c46cSDimitry Andric // get two identical ConstantInt's, then we are good to share them. We use
985dff0c46cSDimitry Andric // the constant folding APIs to do this so that we get the benefit of
9863861d79fSDimitry Andric // DataLayout.
987dff0c46cSDimitry Andric if (isa<PointerType>(A->getType()))
9883ca95b02SDimitry Andric A = ConstantFoldCastOperand(Instruction::PtrToInt,
9893ca95b02SDimitry Andric const_cast<Constant *>(A), IntTy, DL);
990dff0c46cSDimitry Andric else if (A->getType() != IntTy)
9913ca95b02SDimitry Andric A = ConstantFoldCastOperand(Instruction::BitCast, const_cast<Constant *>(A),
9923ca95b02SDimitry Andric IntTy, DL);
993dff0c46cSDimitry Andric if (isa<PointerType>(B->getType()))
9943ca95b02SDimitry Andric B = ConstantFoldCastOperand(Instruction::PtrToInt,
9953ca95b02SDimitry Andric const_cast<Constant *>(B), IntTy, DL);
996dff0c46cSDimitry Andric else if (B->getType() != IntTy)
9973ca95b02SDimitry Andric B = ConstantFoldCastOperand(Instruction::BitCast, const_cast<Constant *>(B),
9983ca95b02SDimitry Andric IntTy, DL);
999f22ef01cSRoman Divacky
1000dff0c46cSDimitry Andric return A == B;
1001f22ef01cSRoman Divacky }
1002f22ef01cSRoman Divacky
10038f0fd8f6SDimitry Andric /// Create a new entry in the constant pool or return an existing one.
10048f0fd8f6SDimitry Andric /// User must specify the log2 of the minimum required alignment for the object.
getConstantPoolIndex(const Constant * C,unsigned Alignment)1005f22ef01cSRoman Divacky unsigned MachineConstantPool::getConstantPoolIndex(const Constant *C,
1006f22ef01cSRoman Divacky unsigned Alignment) {
1007f22ef01cSRoman Divacky assert(Alignment && "Alignment must be specified!");
1008f22ef01cSRoman Divacky if (Alignment > PoolAlignment) PoolAlignment = Alignment;
1009f22ef01cSRoman Divacky
1010f22ef01cSRoman Divacky // Check to see if we already have this constant.
1011f22ef01cSRoman Divacky //
1012f22ef01cSRoman Divacky // FIXME, this could be made much more efficient for large constant pools.
1013f22ef01cSRoman Divacky for (unsigned i = 0, e = Constants.size(); i != e; ++i)
1014f22ef01cSRoman Divacky if (!Constants[i].isMachineConstantPoolEntry() &&
1015875ed548SDimitry Andric CanShareConstantPoolEntry(Constants[i].Val.ConstVal, C, DL)) {
1016f22ef01cSRoman Divacky if ((unsigned)Constants[i].getAlignment() < Alignment)
1017f22ef01cSRoman Divacky Constants[i].Alignment = Alignment;
1018f22ef01cSRoman Divacky return i;
1019f22ef01cSRoman Divacky }
1020f22ef01cSRoman Divacky
1021f22ef01cSRoman Divacky Constants.push_back(MachineConstantPoolEntry(C, Alignment));
1022f22ef01cSRoman Divacky return Constants.size()-1;
1023f22ef01cSRoman Divacky }
1024f22ef01cSRoman Divacky
getConstantPoolIndex(MachineConstantPoolValue * V,unsigned Alignment)1025f22ef01cSRoman Divacky unsigned MachineConstantPool::getConstantPoolIndex(MachineConstantPoolValue *V,
1026f22ef01cSRoman Divacky unsigned Alignment) {
1027f22ef01cSRoman Divacky assert(Alignment && "Alignment must be specified!");
1028f22ef01cSRoman Divacky if (Alignment > PoolAlignment) PoolAlignment = Alignment;
1029f22ef01cSRoman Divacky
1030f22ef01cSRoman Divacky // Check to see if we already have this constant.
1031f22ef01cSRoman Divacky //
1032f22ef01cSRoman Divacky // FIXME, this could be made much more efficient for large constant pools.
1033f22ef01cSRoman Divacky int Idx = V->getExistingMachineCPValue(this, Alignment);
1034dd6029ffSDimitry Andric if (Idx != -1) {
1035dd6029ffSDimitry Andric MachineCPVsSharingEntries.insert(V);
1036f22ef01cSRoman Divacky return (unsigned)Idx;
1037dd6029ffSDimitry Andric }
1038f22ef01cSRoman Divacky
1039f22ef01cSRoman Divacky Constants.push_back(MachineConstantPoolEntry(V, Alignment));
1040f22ef01cSRoman Divacky return Constants.size()-1;
1041f22ef01cSRoman Divacky }
1042f22ef01cSRoman Divacky
print(raw_ostream & OS) const1043f22ef01cSRoman Divacky void MachineConstantPool::print(raw_ostream &OS) const {
1044f22ef01cSRoman Divacky if (Constants.empty()) return;
1045f22ef01cSRoman Divacky
1046f22ef01cSRoman Divacky OS << "Constant Pool:\n";
1047f22ef01cSRoman Divacky for (unsigned i = 0, e = Constants.size(); i != e; ++i) {
1048f22ef01cSRoman Divacky OS << " cp#" << i << ": ";
1049f22ef01cSRoman Divacky if (Constants[i].isMachineConstantPoolEntry())
1050f22ef01cSRoman Divacky Constants[i].Val.MachineCPVal->print(OS);
1051f22ef01cSRoman Divacky else
105291bc56edSDimitry Andric Constants[i].Val.ConstVal->printAsOperand(OS, /*PrintType=*/false);
1053f22ef01cSRoman Divacky OS << ", align=" << Constants[i].getAlignment();
1054f22ef01cSRoman Divacky OS << "\n";
1055f22ef01cSRoman Divacky }
1056f22ef01cSRoman Divacky }
1057f22ef01cSRoman Divacky
10583861d79fSDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const10593ca95b02SDimitry Andric LLVM_DUMP_METHOD void MachineConstantPool::dump() const { print(dbgs()); }
10603861d79fSDimitry Andric #endif
1061