27 auto Key = std::make_pair(
MBB, Val);
28 auto It = VRegDefMap.find(
Key);
33 if (It == VRegDefMap.end()) {
34 auto &
DL = MF->getDataLayout();
36 auto VReg = MF->getRegInfo().createVirtualRegister(RC);
37 VRegDefMap[
Key] = VReg;
38 VRegUpwardsUse[
Key] = VReg;
46 VRegDefMap[std::make_pair(
MBB, Val)] = VReg;
52 auto It = VRegDefUses.find(
Key);
53 if (It != VRegDefUses.end())
56 auto &
DL = MF->getDataLayout();
58 Register VReg = MF->getRegInfo().createVirtualRegister(RC);
59 VRegDefUses[
Key] = VReg;
67 auto It = VRegDefUses.find(
Key);
68 if (It != VRegDefUses.end())
72 VRegDefUses[
Key] = VReg;
81 TLI = MF->getSubtarget().getTargetLowering();
82 TII = MF->getSubtarget().getInstrInfo();
84 SwiftErrorVals.clear();
86 VRegUpwardsUse.clear();
88 SwiftErrorArg =
nullptr;
90 if (!TLI->supportSwiftError())
94 bool HaveSeenSwiftErrorArg =
false;
97 if (AI->hasSwiftErrorAttr()) {
98 assert(!HaveSeenSwiftErrorArg &&
99 "Must have only one swifterror parameter");
100 (void)HaveSeenSwiftErrorArg;
101 HaveSeenSwiftErrorArg =
true;
102 SwiftErrorArg = &*AI;
103 SwiftErrorVals.push_back(&*AI);
106 for (
const auto &LLVMBB : *Fn)
107 for (
const auto &Inst : LLVMBB) {
109 if (Alloca->isSwiftError())
110 SwiftErrorVals.push_back(Alloca);
115 if (!TLI->supportSwiftError())
120 if (SwiftErrorVals.empty())
124 auto &
DL = MF->getDataLayout();
125 auto const *RC = TLI->getRegClassFor(TLI->getPointerTy(
DL));
126 bool Inserted =
false;
127 for (
const auto *SwiftErrorVal : SwiftErrorVals) {
130 if (SwiftErrorArg && SwiftErrorArg == SwiftErrorVal)
132 Register VReg = MF->getRegInfo().createVirtualRegister(RC);
136 TII->
get(TargetOpcode::IMPLICIT_DEF), VReg);
147 if (!TLI->supportSwiftError())
152 if (SwiftErrorVals.empty())
159 for (
const auto *SwiftErrorVal : SwiftErrorVals) {
160 auto Key = std::make_pair(
MBB, SwiftErrorVal);
161 auto UUseIt = VRegUpwardsUse.find(
Key);
162 auto VRegDefIt = VRegDefMap.find(
Key);
163 bool UpwardsUse = UUseIt != VRegUpwardsUse.end();
165 bool DownwardDef = VRegDefIt != VRegDefMap.end();
166 assert(!(UpwardsUse && !DownwardDef) &&
167 "We can't have an upwards use but no downwards def");
172 if (!UpwardsUse && DownwardDef)
182 for (
auto *Pred :
MBB->predecessors()) {
183 if (!Visited.
insert(Pred).second)
194 UUseIt = VRegUpwardsUse.find(
Key);
195 assert(UUseIt != VRegUpwardsUse.end());
196 UUseVReg = UUseIt->second;
206 [&](
const std::pair<const MachineBasicBlock *, Register> &V)
207 ->
bool {
return V.second != VRegs[0].second; });
211 if (!UpwardsUse && !needPHI) {
213 "No predecessors? The entry block should bail out earlier");
222 const auto *TII = MF->getSubtarget().getInstrInfo();
228 "No predecessors? Is the Calling Convention correct?");
230 BuildMI(*
MBB,
MBB->getFirstNonPHI(), DLoc, TII->get(TargetOpcode::COPY),
238 auto &
DL = MF->getDataLayout();
239 auto const *RC = TLI->getRegClassFor(TLI->getPointerTy(
DL));
241 UpwardsUse ? UUseVReg : MF->getRegInfo().createVirtualRegister(RC);
244 TII->get(TargetOpcode::PHI), PHIVReg);
245 for (
auto BBRegPair : VRegs) {
246 PHI.addReg(BBRegPair.second).addMBB(BBRegPair.first);
258 for (
const auto &
Use : VRegUpwardsUse) {
264#ifdef EXPENSIVE_CHECKS
266 "Reachable block has VReg upward use without definition.");
272 TII->
get(TargetOpcode::IMPLICIT_DEF), VReg);
279 if (!TLI->supportSwiftError() || SwiftErrorVals.empty())
283 for (
auto It = Begin; It != End; ++It) {
286 const Value *SwiftErrorAddr =
nullptr;
287 for (
const auto &Arg : CB->args()) {
288 if (!Arg->isSwiftError())
291 assert(!SwiftErrorAddr &&
"Cannot have multiple swifterror arguments");
292 SwiftErrorAddr = &*Arg;
294 "Must have a swifterror value argument");
305 const Value *V = LI->getOperand(0);
306 if (!V->isSwiftError())
313 const Value *SwiftErrorAddr =
SI->getOperand(1);
322 const Function *
F = R->getParent()->getParent();
323 if (!
F->getAttributes().hasAttrSomewhere(Attribute::SwiftError))
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Promote Memory to Register
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
This file describes how to lower LLVM code to machine code.
an instruction to allocate memory on the stack
InstListType::const_iterator const_iterator
const Argument * const_arg_iterator
An instruction for reading from memory.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
LLVM_ABI iterator getFirstNonPHI()
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
bool def_empty(Register RegNo) const
def_empty - Return true if there are no instructions defining the specified register (it may be live-...
PointerIntPair - This class implements a pair of a pointer and small integer.
Wrapper class representing virtual and physical registers.
Return a value (possibly void), from a function.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
LLVM_ABI bool createEntriesInEntryBlock(DebugLoc DbgLoc)
Create initial definitions of swifterror values in the entry block of the current function.
LLVM_ABI void setFunction(MachineFunction &MF)
Initialize data structures for specified new function.
LLVM_ABI Register getOrCreateVReg(const MachineBasicBlock *, const Value *)
Get or create the swifterror value virtual register in VRegDefMap for this basic block.
LLVM_ABI void setCurrentVReg(const MachineBasicBlock *MBB, const Value *, Register)
Set the swifterror virtual register in the VRegDefMap for this basic block.
LLVM_ABI Register getOrCreateVRegUseAt(const Instruction *, const MachineBasicBlock *, const Value *)
Get or create the swifterror value virtual register for a use of a swifterror by an instruction.
LLVM_ABI void preassignVRegs(MachineBasicBlock *MBB, BasicBlock::const_iterator Begin, BasicBlock::const_iterator End)
LLVM_ABI Register getOrCreateVRegDefAt(const Instruction *, const MachineBasicBlock *, const Value *)
Get or create the swifterror value virtual register for a def of a swifterror by an instruction.
LLVM_ABI void propagateVRegs()
Propagate assigned swifterror vregs through a function, synthesizing PHI nodes when needed to maintai...
A Use represents the edge between a Value definition and its users.
LLVM Value Representation.
LLVM_ABI bool isSwiftError() const
Return true if this value is a swifterror value.
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.