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