1//===- SwiftErrorValueTracking.h - Track swifterror VReg vals --*- C++ -*--===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This implements a limited mem2reg-like analysis to promote uses of function
10// arguments and allocas marked with swiftalloc from memory into virtual
11// registers tracked by this class.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_CODEGEN_SWIFTERRORVALUETRACKING_H
16#define LLVM_CODEGEN_SWIFTERRORVALUETRACKING_H
17
18#include "llvm/ADT/DenseMap.h"
19#include "llvm/ADT/SmallVector.h"
20#include "llvm/CodeGen/Register.h"
21#include "llvm/IR/BasicBlock.h"
22#include "llvm/IR/DebugLoc.h"
23#include <functional>
24#include <type_traits>
25#include <utility>
26
27
28namespace llvm {
29 class Function;
30 class MachineBasicBlock;
31 class MachineFunction;
32 class MachineInstr;
33 class TargetInstrInfo;
34 class TargetLowering;
35
36class SwiftErrorValueTracking {
37 // Some useful objects to reduce the number of function arguments needed.
38 MachineFunction *MF;
39 const Function *Fn;
40 const TargetLowering *TLI;
41 const TargetInstrInfo *TII;
42
43 /// A map from swifterror value in a basic block to the virtual register it is
44 /// currently represented by.
45 DenseMap<std::pair<const MachineBasicBlock *, const Value *>, Register>
46 VRegDefMap;
47
48 /// A list of upward exposed vreg uses that need to be satisfied by either a
49 /// copy def or a phi node at the beginning of the basic block representing
50 /// the predecessor(s) swifterror value.
51 DenseMap<std::pair<const MachineBasicBlock *, const Value *>, Register>
52 VRegUpwardsUse;
53
54 /// A map from instructions that define/use a swifterror value to the virtual
55 /// register that represents that def/use.
56 llvm::DenseMap<PointerIntPair<const Instruction *, 1, bool>, Register>
57 VRegDefUses;
58
59 /// The swifterror argument of the current function.
60 const Value *SwiftErrorArg;
61
62 using SwiftErrorValues = SmallVector<const Value*, 1>;
63 /// A function can only have a single swifterror argument. And if it does
64 /// have a swifterror argument, it must be the first entry in
65 /// SwiftErrorVals.
66 SwiftErrorValues SwiftErrorVals;
67
68public:
69 /// Initialize data structures for specified new function.
70 void setFunction(MachineFunction &MF);
71
72 /// Get the (unique) function argument that was marked swifterror, or nullptr
73 /// if this function has no swifterror args.
74 const Value *getFunctionArg() const {
75 return SwiftErrorArg;
76 }
77
78 /// Get or create the swifterror value virtual register in
79 /// VRegDefMap for this basic block.
80 Register getOrCreateVReg(const MachineBasicBlock *, const Value *);
81
82 /// Set the swifterror virtual register in the VRegDefMap for this
83 /// basic block.
84 void setCurrentVReg(const MachineBasicBlock *MBB, const Value *, Register);
85
86 /// Get or create the swifterror value virtual register for a def of a
87 /// swifterror by an instruction.
88 Register getOrCreateVRegDefAt(const Instruction *, const MachineBasicBlock *,
89 const Value *);
90
91 /// Get or create the swifterror value virtual register for a use of a
92 /// swifterror by an instruction.
93 Register getOrCreateVRegUseAt(const Instruction *, const MachineBasicBlock *,
94 const Value *);
95
96 /// Create initial definitions of swifterror values in the entry block of the
97 /// current function.
98 bool createEntriesInEntryBlock(DebugLoc DbgLoc);
99
100 /// Propagate assigned swifterror vregs through a function, synthesizing PHI
101 /// nodes when needed to maintain consistency.
102 void propagateVRegs();
103
104 void preassignVRegs(MachineBasicBlock *MBB, BasicBlock::const_iterator Begin,
105 BasicBlock::const_iterator End);
106};
107
108}
109
110#endif
111