diff options
author | orivej <orivej@yandex-team.ru> | 2022-02-10 16:44:49 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:44:49 +0300 |
commit | 718c552901d703c502ccbefdfc3c9028d608b947 (patch) | |
tree | 46534a98bbefcd7b1f3faa5b52c138ab27db75b7 /contrib/libs/llvm12/lib/CodeGen/SwiftErrorValueTracking.cpp | |
parent | e9656aae26e0358d5378e5b63dcac5c8dbe0e4d0 (diff) | |
download | ydb-718c552901d703c502ccbefdfc3c9028d608b947.tar.gz |
Restoring authorship annotation for <orivej@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/libs/llvm12/lib/CodeGen/SwiftErrorValueTracking.cpp')
-rw-r--r-- | contrib/libs/llvm12/lib/CodeGen/SwiftErrorValueTracking.cpp | 620 |
1 files changed, 310 insertions, 310 deletions
diff --git a/contrib/libs/llvm12/lib/CodeGen/SwiftErrorValueTracking.cpp b/contrib/libs/llvm12/lib/CodeGen/SwiftErrorValueTracking.cpp index 4408011c95..00f0ec208d 100644 --- a/contrib/libs/llvm12/lib/CodeGen/SwiftErrorValueTracking.cpp +++ b/contrib/libs/llvm12/lib/CodeGen/SwiftErrorValueTracking.cpp @@ -1,312 +1,312 @@ -//===-- SwiftErrorValueTracking.cpp --------------------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This implements a limited mem2reg-like analysis to promote uses of function -// arguments and allocas marked with swiftalloc from memory into virtual -// registers tracked by this class. -// -//===----------------------------------------------------------------------===// - -#include "llvm/CodeGen/SwiftErrorValueTracking.h" -#include "llvm/ADT/PostOrderIterator.h" -#include "llvm/ADT/SmallSet.h" -#include "llvm/CodeGen/MachineInstrBuilder.h" -#include "llvm/CodeGen/MachineRegisterInfo.h" -#include "llvm/CodeGen/TargetInstrInfo.h" -#include "llvm/CodeGen/TargetLowering.h" -#include "llvm/IR/Value.h" - -using namespace llvm; - -Register SwiftErrorValueTracking::getOrCreateVReg(const MachineBasicBlock *MBB, - const Value *Val) { - auto Key = std::make_pair(MBB, Val); - auto It = VRegDefMap.find(Key); - // If this is the first use of this swifterror value in this basic block, - // create a new virtual register. - // After we processed all basic blocks we will satisfy this "upwards exposed - // use" by inserting a copy or phi at the beginning of this block. - if (It == VRegDefMap.end()) { - auto &DL = MF->getDataLayout(); - const TargetRegisterClass *RC = TLI->getRegClassFor(TLI->getPointerTy(DL)); - auto VReg = MF->getRegInfo().createVirtualRegister(RC); - VRegDefMap[Key] = VReg; - VRegUpwardsUse[Key] = VReg; - return VReg; - } else - return It->second; -} - -void SwiftErrorValueTracking::setCurrentVReg(const MachineBasicBlock *MBB, - const Value *Val, Register VReg) { - VRegDefMap[std::make_pair(MBB, Val)] = VReg; -} - -Register SwiftErrorValueTracking::getOrCreateVRegDefAt( - const Instruction *I, const MachineBasicBlock *MBB, const Value *Val) { - auto Key = PointerIntPair<const Instruction *, 1, bool>(I, true); - auto It = VRegDefUses.find(Key); - if (It != VRegDefUses.end()) - return It->second; - - auto &DL = MF->getDataLayout(); - const TargetRegisterClass *RC = TLI->getRegClassFor(TLI->getPointerTy(DL)); - Register VReg = MF->getRegInfo().createVirtualRegister(RC); - VRegDefUses[Key] = VReg; - setCurrentVReg(MBB, Val, VReg); - return VReg; -} - -Register SwiftErrorValueTracking::getOrCreateVRegUseAt( - const Instruction *I, const MachineBasicBlock *MBB, const Value *Val) { - auto Key = PointerIntPair<const Instruction *, 1, bool>(I, false); - auto It = VRegDefUses.find(Key); - if (It != VRegDefUses.end()) - return It->second; - - Register VReg = getOrCreateVReg(MBB, Val); - VRegDefUses[Key] = VReg; - return VReg; -} - -/// Set up SwiftErrorVals by going through the function. If the function has -/// swifterror argument, it will be the first entry. -void SwiftErrorValueTracking::setFunction(MachineFunction &mf) { - MF = &mf; - Fn = &MF->getFunction(); - TLI = MF->getSubtarget().getTargetLowering(); - TII = MF->getSubtarget().getInstrInfo(); - - if (!TLI->supportSwiftError()) - return; - - SwiftErrorVals.clear(); - VRegDefMap.clear(); - VRegUpwardsUse.clear(); - VRegDefUses.clear(); - SwiftErrorArg = nullptr; - - // Check if function has a swifterror argument. - bool HaveSeenSwiftErrorArg = false; - for (Function::const_arg_iterator AI = Fn->arg_begin(), AE = Fn->arg_end(); - AI != AE; ++AI) - if (AI->hasSwiftErrorAttr()) { - assert(!HaveSeenSwiftErrorArg && - "Must have only one swifterror parameter"); - (void)HaveSeenSwiftErrorArg; // silence warning. - HaveSeenSwiftErrorArg = true; - SwiftErrorArg = &*AI; - SwiftErrorVals.push_back(&*AI); - } - - for (const auto &LLVMBB : *Fn) - for (const auto &Inst : LLVMBB) { - if (const AllocaInst *Alloca = dyn_cast<AllocaInst>(&Inst)) - if (Alloca->isSwiftError()) - SwiftErrorVals.push_back(Alloca); - } -} - -bool SwiftErrorValueTracking::createEntriesInEntryBlock(DebugLoc DbgLoc) { - if (!TLI->supportSwiftError()) - return false; - - // We only need to do this when we have swifterror parameter or swifterror - // alloc. - if (SwiftErrorVals.empty()) - return false; - - MachineBasicBlock *MBB = &*MF->begin(); - auto &DL = MF->getDataLayout(); - auto const *RC = TLI->getRegClassFor(TLI->getPointerTy(DL)); - bool Inserted = false; - for (const auto *SwiftErrorVal : SwiftErrorVals) { - // We will always generate a copy from the argument. It is always used at - // least by the 'return' of the swifterror. - if (SwiftErrorArg && SwiftErrorArg == SwiftErrorVal) - continue; - Register VReg = MF->getRegInfo().createVirtualRegister(RC); - // Assign Undef to Vreg. We construct MI directly to make sure it works - // with FastISel. - BuildMI(*MBB, MBB->getFirstNonPHI(), DbgLoc, - TII->get(TargetOpcode::IMPLICIT_DEF), VReg); - - setCurrentVReg(MBB, SwiftErrorVal, VReg); - Inserted = true; - } - - return Inserted; -} - -/// Propagate swifterror values through the machine function CFG. -void SwiftErrorValueTracking::propagateVRegs() { - if (!TLI->supportSwiftError()) - return; - - // We only need to do this when we have swifterror parameter or swifterror - // alloc. - if (SwiftErrorVals.empty()) - return; - - // For each machine basic block in reverse post order. - ReversePostOrderTraversal<MachineFunction *> RPOT(MF); - for (MachineBasicBlock *MBB : RPOT) { - // For each swifterror value in the function. - for (const auto *SwiftErrorVal : SwiftErrorVals) { - auto Key = std::make_pair(MBB, SwiftErrorVal); - auto UUseIt = VRegUpwardsUse.find(Key); - auto VRegDefIt = VRegDefMap.find(Key); - bool UpwardsUse = UUseIt != VRegUpwardsUse.end(); - Register UUseVReg = UpwardsUse ? UUseIt->second : Register(); - bool DownwardDef = VRegDefIt != VRegDefMap.end(); - assert(!(UpwardsUse && !DownwardDef) && - "We can't have an upwards use but no downwards def"); - - // If there is no upwards exposed use and an entry for the swifterror in - // the def map for this value we don't need to do anything: We already - // have a downward def for this basic block. - if (!UpwardsUse && DownwardDef) - continue; - - // Otherwise we either have an upwards exposed use vreg that we need to - // materialize or need to forward the downward def from predecessors. - - // Check whether we have a single vreg def from all predecessors. - // Otherwise we need a phi. - SmallVector<std::pair<MachineBasicBlock *, Register>, 4> VRegs; - SmallSet<const MachineBasicBlock *, 8> Visited; - for (auto *Pred : MBB->predecessors()) { - if (!Visited.insert(Pred).second) - continue; - VRegs.push_back(std::make_pair( - Pred, getOrCreateVReg(Pred, SwiftErrorVal))); - if (Pred != MBB) - continue; - // We have a self-edge. - // If there was no upwards use in this basic block there is now one: the - // phi needs to use it self. - if (!UpwardsUse) { - UpwardsUse = true; - UUseIt = VRegUpwardsUse.find(Key); - assert(UUseIt != VRegUpwardsUse.end()); - UUseVReg = UUseIt->second; - } - } - - // We need a phi node if we have more than one predecessor with different - // downward defs. - bool needPHI = - VRegs.size() >= 1 && +//===-- SwiftErrorValueTracking.cpp --------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This implements a limited mem2reg-like analysis to promote uses of function +// arguments and allocas marked with swiftalloc from memory into virtual +// registers tracked by this class. +// +//===----------------------------------------------------------------------===// + +#include "llvm/CodeGen/SwiftErrorValueTracking.h" +#include "llvm/ADT/PostOrderIterator.h" +#include "llvm/ADT/SmallSet.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/CodeGen/TargetInstrInfo.h" +#include "llvm/CodeGen/TargetLowering.h" +#include "llvm/IR/Value.h" + +using namespace llvm; + +Register SwiftErrorValueTracking::getOrCreateVReg(const MachineBasicBlock *MBB, + const Value *Val) { + auto Key = std::make_pair(MBB, Val); + auto It = VRegDefMap.find(Key); + // If this is the first use of this swifterror value in this basic block, + // create a new virtual register. + // After we processed all basic blocks we will satisfy this "upwards exposed + // use" by inserting a copy or phi at the beginning of this block. + if (It == VRegDefMap.end()) { + auto &DL = MF->getDataLayout(); + const TargetRegisterClass *RC = TLI->getRegClassFor(TLI->getPointerTy(DL)); + auto VReg = MF->getRegInfo().createVirtualRegister(RC); + VRegDefMap[Key] = VReg; + VRegUpwardsUse[Key] = VReg; + return VReg; + } else + return It->second; +} + +void SwiftErrorValueTracking::setCurrentVReg(const MachineBasicBlock *MBB, + const Value *Val, Register VReg) { + VRegDefMap[std::make_pair(MBB, Val)] = VReg; +} + +Register SwiftErrorValueTracking::getOrCreateVRegDefAt( + const Instruction *I, const MachineBasicBlock *MBB, const Value *Val) { + auto Key = PointerIntPair<const Instruction *, 1, bool>(I, true); + auto It = VRegDefUses.find(Key); + if (It != VRegDefUses.end()) + return It->second; + + auto &DL = MF->getDataLayout(); + const TargetRegisterClass *RC = TLI->getRegClassFor(TLI->getPointerTy(DL)); + Register VReg = MF->getRegInfo().createVirtualRegister(RC); + VRegDefUses[Key] = VReg; + setCurrentVReg(MBB, Val, VReg); + return VReg; +} + +Register SwiftErrorValueTracking::getOrCreateVRegUseAt( + const Instruction *I, const MachineBasicBlock *MBB, const Value *Val) { + auto Key = PointerIntPair<const Instruction *, 1, bool>(I, false); + auto It = VRegDefUses.find(Key); + if (It != VRegDefUses.end()) + return It->second; + + Register VReg = getOrCreateVReg(MBB, Val); + VRegDefUses[Key] = VReg; + return VReg; +} + +/// Set up SwiftErrorVals by going through the function. If the function has +/// swifterror argument, it will be the first entry. +void SwiftErrorValueTracking::setFunction(MachineFunction &mf) { + MF = &mf; + Fn = &MF->getFunction(); + TLI = MF->getSubtarget().getTargetLowering(); + TII = MF->getSubtarget().getInstrInfo(); + + if (!TLI->supportSwiftError()) + return; + + SwiftErrorVals.clear(); + VRegDefMap.clear(); + VRegUpwardsUse.clear(); + VRegDefUses.clear(); + SwiftErrorArg = nullptr; + + // Check if function has a swifterror argument. + bool HaveSeenSwiftErrorArg = false; + for (Function::const_arg_iterator AI = Fn->arg_begin(), AE = Fn->arg_end(); + AI != AE; ++AI) + if (AI->hasSwiftErrorAttr()) { + assert(!HaveSeenSwiftErrorArg && + "Must have only one swifterror parameter"); + (void)HaveSeenSwiftErrorArg; // silence warning. + HaveSeenSwiftErrorArg = true; + SwiftErrorArg = &*AI; + SwiftErrorVals.push_back(&*AI); + } + + for (const auto &LLVMBB : *Fn) + for (const auto &Inst : LLVMBB) { + if (const AllocaInst *Alloca = dyn_cast<AllocaInst>(&Inst)) + if (Alloca->isSwiftError()) + SwiftErrorVals.push_back(Alloca); + } +} + +bool SwiftErrorValueTracking::createEntriesInEntryBlock(DebugLoc DbgLoc) { + if (!TLI->supportSwiftError()) + return false; + + // We only need to do this when we have swifterror parameter or swifterror + // alloc. + if (SwiftErrorVals.empty()) + return false; + + MachineBasicBlock *MBB = &*MF->begin(); + auto &DL = MF->getDataLayout(); + auto const *RC = TLI->getRegClassFor(TLI->getPointerTy(DL)); + bool Inserted = false; + for (const auto *SwiftErrorVal : SwiftErrorVals) { + // We will always generate a copy from the argument. It is always used at + // least by the 'return' of the swifterror. + if (SwiftErrorArg && SwiftErrorArg == SwiftErrorVal) + continue; + Register VReg = MF->getRegInfo().createVirtualRegister(RC); + // Assign Undef to Vreg. We construct MI directly to make sure it works + // with FastISel. + BuildMI(*MBB, MBB->getFirstNonPHI(), DbgLoc, + TII->get(TargetOpcode::IMPLICIT_DEF), VReg); + + setCurrentVReg(MBB, SwiftErrorVal, VReg); + Inserted = true; + } + + return Inserted; +} + +/// Propagate swifterror values through the machine function CFG. +void SwiftErrorValueTracking::propagateVRegs() { + if (!TLI->supportSwiftError()) + return; + + // We only need to do this when we have swifterror parameter or swifterror + // alloc. + if (SwiftErrorVals.empty()) + return; + + // For each machine basic block in reverse post order. + ReversePostOrderTraversal<MachineFunction *> RPOT(MF); + for (MachineBasicBlock *MBB : RPOT) { + // For each swifterror value in the function. + for (const auto *SwiftErrorVal : SwiftErrorVals) { + auto Key = std::make_pair(MBB, SwiftErrorVal); + auto UUseIt = VRegUpwardsUse.find(Key); + auto VRegDefIt = VRegDefMap.find(Key); + bool UpwardsUse = UUseIt != VRegUpwardsUse.end(); + Register UUseVReg = UpwardsUse ? UUseIt->second : Register(); + bool DownwardDef = VRegDefIt != VRegDefMap.end(); + assert(!(UpwardsUse && !DownwardDef) && + "We can't have an upwards use but no downwards def"); + + // If there is no upwards exposed use and an entry for the swifterror in + // the def map for this value we don't need to do anything: We already + // have a downward def for this basic block. + if (!UpwardsUse && DownwardDef) + continue; + + // Otherwise we either have an upwards exposed use vreg that we need to + // materialize or need to forward the downward def from predecessors. + + // Check whether we have a single vreg def from all predecessors. + // Otherwise we need a phi. + SmallVector<std::pair<MachineBasicBlock *, Register>, 4> VRegs; + SmallSet<const MachineBasicBlock *, 8> Visited; + for (auto *Pred : MBB->predecessors()) { + if (!Visited.insert(Pred).second) + continue; + VRegs.push_back(std::make_pair( + Pred, getOrCreateVReg(Pred, SwiftErrorVal))); + if (Pred != MBB) + continue; + // We have a self-edge. + // If there was no upwards use in this basic block there is now one: the + // phi needs to use it self. + if (!UpwardsUse) { + UpwardsUse = true; + UUseIt = VRegUpwardsUse.find(Key); + assert(UUseIt != VRegUpwardsUse.end()); + UUseVReg = UUseIt->second; + } + } + + // We need a phi node if we have more than one predecessor with different + // downward defs. + bool needPHI = + VRegs.size() >= 1 && llvm::find_if( VRegs, - [&](const std::pair<const MachineBasicBlock *, Register> &V) - -> bool { return V.second != VRegs[0].second; }) != - VRegs.end(); - - // If there is no upwards exposed used and we don't need a phi just - // forward the swifterror vreg from the predecessor(s). - if (!UpwardsUse && !needPHI) { - assert(!VRegs.empty() && - "No predecessors? The entry block should bail out earlier"); - // Just forward the swifterror vreg from the predecessor(s). - setCurrentVReg(MBB, SwiftErrorVal, VRegs[0].second); - continue; - } - - auto DLoc = isa<Instruction>(SwiftErrorVal) - ? cast<Instruction>(SwiftErrorVal)->getDebugLoc() - : DebugLoc(); - const auto *TII = MF->getSubtarget().getInstrInfo(); - - // If we don't need a phi create a copy to the upward exposed vreg. - if (!needPHI) { - assert(UpwardsUse); - assert(!VRegs.empty() && - "No predecessors? Is the Calling Convention correct?"); - Register DestReg = UUseVReg; - BuildMI(*MBB, MBB->getFirstNonPHI(), DLoc, TII->get(TargetOpcode::COPY), - DestReg) - .addReg(VRegs[0].second); - continue; - } - - // We need a phi: if there is an upwards exposed use we already have a - // destination virtual register number otherwise we generate a new one. - auto &DL = MF->getDataLayout(); - auto const *RC = TLI->getRegClassFor(TLI->getPointerTy(DL)); - Register PHIVReg = - UpwardsUse ? UUseVReg : MF->getRegInfo().createVirtualRegister(RC); - MachineInstrBuilder PHI = - BuildMI(*MBB, MBB->getFirstNonPHI(), DLoc, - TII->get(TargetOpcode::PHI), PHIVReg); - for (auto BBRegPair : VRegs) { - PHI.addReg(BBRegPair.second).addMBB(BBRegPair.first); - } - - // We did not have a definition in this block before: store the phi's vreg - // as this block downward exposed def. - if (!UpwardsUse) - setCurrentVReg(MBB, SwiftErrorVal, PHIVReg); - } - } -} - -void SwiftErrorValueTracking::preassignVRegs( - MachineBasicBlock *MBB, BasicBlock::const_iterator Begin, - BasicBlock::const_iterator End) { - if (!TLI->supportSwiftError() || SwiftErrorVals.empty()) - return; - - // Iterator over instructions and assign vregs to swifterror defs and uses. - for (auto It = Begin; It != End; ++It) { - if (auto *CB = dyn_cast<CallBase>(&*It)) { - // A call-site with a swifterror argument is both use and def. - const Value *SwiftErrorAddr = nullptr; - for (auto &Arg : CB->args()) { - if (!Arg->isSwiftError()) - continue; - // Use of swifterror. - assert(!SwiftErrorAddr && "Cannot have multiple swifterror arguments"); - SwiftErrorAddr = &*Arg; - assert(SwiftErrorAddr->isSwiftError() && - "Must have a swifterror value argument"); - getOrCreateVRegUseAt(&*It, MBB, SwiftErrorAddr); - } - if (!SwiftErrorAddr) - continue; - - // Def of swifterror. - getOrCreateVRegDefAt(&*It, MBB, SwiftErrorAddr); - - // A load is a use. - } else if (const LoadInst *LI = dyn_cast<const LoadInst>(&*It)) { - const Value *V = LI->getOperand(0); - if (!V->isSwiftError()) - continue; - - getOrCreateVRegUseAt(LI, MBB, V); - - // A store is a def. - } else if (const StoreInst *SI = dyn_cast<const StoreInst>(&*It)) { - const Value *SwiftErrorAddr = SI->getOperand(1); - if (!SwiftErrorAddr->isSwiftError()) - continue; - - // Def of swifterror. - getOrCreateVRegDefAt(&*It, MBB, SwiftErrorAddr); - - // A return in a swiferror returning function is a use. - } else if (const ReturnInst *R = dyn_cast<const ReturnInst>(&*It)) { - const Function *F = R->getParent()->getParent(); - if (!F->getAttributes().hasAttrSomewhere(Attribute::SwiftError)) - continue; - - getOrCreateVRegUseAt(R, MBB, SwiftErrorArg); - } - } -} + [&](const std::pair<const MachineBasicBlock *, Register> &V) + -> bool { return V.second != VRegs[0].second; }) != + VRegs.end(); + + // If there is no upwards exposed used and we don't need a phi just + // forward the swifterror vreg from the predecessor(s). + if (!UpwardsUse && !needPHI) { + assert(!VRegs.empty() && + "No predecessors? The entry block should bail out earlier"); + // Just forward the swifterror vreg from the predecessor(s). + setCurrentVReg(MBB, SwiftErrorVal, VRegs[0].second); + continue; + } + + auto DLoc = isa<Instruction>(SwiftErrorVal) + ? cast<Instruction>(SwiftErrorVal)->getDebugLoc() + : DebugLoc(); + const auto *TII = MF->getSubtarget().getInstrInfo(); + + // If we don't need a phi create a copy to the upward exposed vreg. + if (!needPHI) { + assert(UpwardsUse); + assert(!VRegs.empty() && + "No predecessors? Is the Calling Convention correct?"); + Register DestReg = UUseVReg; + BuildMI(*MBB, MBB->getFirstNonPHI(), DLoc, TII->get(TargetOpcode::COPY), + DestReg) + .addReg(VRegs[0].second); + continue; + } + + // We need a phi: if there is an upwards exposed use we already have a + // destination virtual register number otherwise we generate a new one. + auto &DL = MF->getDataLayout(); + auto const *RC = TLI->getRegClassFor(TLI->getPointerTy(DL)); + Register PHIVReg = + UpwardsUse ? UUseVReg : MF->getRegInfo().createVirtualRegister(RC); + MachineInstrBuilder PHI = + BuildMI(*MBB, MBB->getFirstNonPHI(), DLoc, + TII->get(TargetOpcode::PHI), PHIVReg); + for (auto BBRegPair : VRegs) { + PHI.addReg(BBRegPair.second).addMBB(BBRegPair.first); + } + + // We did not have a definition in this block before: store the phi's vreg + // as this block downward exposed def. + if (!UpwardsUse) + setCurrentVReg(MBB, SwiftErrorVal, PHIVReg); + } + } +} + +void SwiftErrorValueTracking::preassignVRegs( + MachineBasicBlock *MBB, BasicBlock::const_iterator Begin, + BasicBlock::const_iterator End) { + if (!TLI->supportSwiftError() || SwiftErrorVals.empty()) + return; + + // Iterator over instructions and assign vregs to swifterror defs and uses. + for (auto It = Begin; It != End; ++It) { + if (auto *CB = dyn_cast<CallBase>(&*It)) { + // A call-site with a swifterror argument is both use and def. + const Value *SwiftErrorAddr = nullptr; + for (auto &Arg : CB->args()) { + if (!Arg->isSwiftError()) + continue; + // Use of swifterror. + assert(!SwiftErrorAddr && "Cannot have multiple swifterror arguments"); + SwiftErrorAddr = &*Arg; + assert(SwiftErrorAddr->isSwiftError() && + "Must have a swifterror value argument"); + getOrCreateVRegUseAt(&*It, MBB, SwiftErrorAddr); + } + if (!SwiftErrorAddr) + continue; + + // Def of swifterror. + getOrCreateVRegDefAt(&*It, MBB, SwiftErrorAddr); + + // A load is a use. + } else if (const LoadInst *LI = dyn_cast<const LoadInst>(&*It)) { + const Value *V = LI->getOperand(0); + if (!V->isSwiftError()) + continue; + + getOrCreateVRegUseAt(LI, MBB, V); + + // A store is a def. + } else if (const StoreInst *SI = dyn_cast<const StoreInst>(&*It)) { + const Value *SwiftErrorAddr = SI->getOperand(1); + if (!SwiftErrorAddr->isSwiftError()) + continue; + + // Def of swifterror. + getOrCreateVRegDefAt(&*It, MBB, SwiftErrorAddr); + + // A return in a swiferror returning function is a use. + } else if (const ReturnInst *R = dyn_cast<const ReturnInst>(&*It)) { + const Function *F = R->getParent()->getParent(); + if (!F->getAttributes().hasAttrSomewhere(Attribute::SwiftError)) + continue; + + getOrCreateVRegUseAt(R, MBB, SwiftErrorArg); + } + } +} |