Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/include/llvm/MC/MCInstrAnalysis.h
Line
Count
Source (jump to first uncovered line)
1
//===- llvm/MC/MCInstrAnalysis.h - InstrDesc target hooks -------*- 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 file defines the MCInstrAnalysis class which the MCTargetDescs can
10
// derive from to give additional information to MC.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#ifndef LLVM_MC_MCINSTRANALYSIS_H
15
#define LLVM_MC_MCINSTRANALYSIS_H
16
17
#include "llvm/MC/MCInst.h"
18
#include "llvm/MC/MCInstrDesc.h"
19
#include "llvm/MC/MCInstrInfo.h"
20
#include <cstdint>
21
22
namespace llvm {
23
24
class MCRegisterInfo;
25
class Triple;
26
27
class MCInstrAnalysis {
28
protected:
29
  friend class Target;
30
31
  const MCInstrInfo *Info;
32
33
public:
34
2.83k
  MCInstrAnalysis(const MCInstrInfo *Info) : Info(Info) {}
35
2.82k
  virtual ~MCInstrAnalysis() = default;
36
37
0
  virtual bool isBranch(const MCInst &Inst) const {
38
0
    return Info->get(Inst.getOpcode()).isBranch();
39
0
  }
40
41
191k
  virtual bool isConditionalBranch(const MCInst &Inst) const {
42
191k
    return Info->get(Inst.getOpcode()).isConditionalBranch();
43
191k
  }
44
45
196k
  virtual bool isUnconditionalBranch(const MCInst &Inst) const {
46
196k
    return Info->get(Inst.getOpcode()).isUnconditionalBranch();
47
196k
  }
48
49
0
  virtual bool isIndirectBranch(const MCInst &Inst) const {
50
0
    return Info->get(Inst.getOpcode()).isIndirectBranch();
51
0
  }
52
53
547k
  virtual bool isCall(const MCInst &Inst) const {
54
547k
    return Info->get(Inst.getOpcode()).isCall();
55
547k
  }
56
57
0
  virtual bool isReturn(const MCInst &Inst) const {
58
0
    return Info->get(Inst.getOpcode()).isReturn();
59
0
  }
60
61
0
  virtual bool isTerminator(const MCInst &Inst) const {
62
0
    return Info->get(Inst.getOpcode()).isTerminator();
63
0
  }
64
65
  /// Returns true if at least one of the register writes performed by
66
  /// \param Inst implicitly clears the upper portion of all super-registers.
67
  ///
68
  /// Example: on X86-64, a write to EAX implicitly clears the upper half of
69
  /// RAX. Also (still on x86) an XMM write perfomed by an AVX 128-bit
70
  /// instruction implicitly clears the upper portion of the correspondent
71
  /// YMM register.
72
  ///
73
  /// This method also updates an APInt which is used as mask of register
74
  /// writes. There is one bit for every explicit/implicit write performed by
75
  /// the instruction. If a write implicitly clears its super-registers, then
76
  /// the corresponding bit is set (vic. the corresponding bit is cleared).
77
  ///
78
  /// The first bits in the APint are related to explicit writes. The remaining
79
  /// bits are related to implicit writes. The sequence of writes follows the
80
  /// machine operand sequence. For implicit writes, the sequence is defined by
81
  /// the MCInstrDesc.
82
  ///
83
  /// The assumption is that the bit-width of the APInt is correctly set by
84
  /// the caller. The default implementation conservatively assumes that none of
85
  /// the writes clears the upper portion of a super-register.
86
  virtual bool clearsSuperRegisters(const MCRegisterInfo &MRI,
87
                                    const MCInst &Inst,
88
                                    APInt &Writes) const;
89
90
  /// Returns true if MI is a dependency breaking zero-idiom for the given
91
  /// subtarget.
92
  ///
93
  /// Mask is used to identify input operands that have their dependency
94
  /// broken. Each bit of the mask is associated with a specific input operand.
95
  /// Bits associated with explicit input operands are laid out first in the
96
  /// mask; implicit operands come after explicit operands.
97
  /// 
98
  /// Dependencies are broken only for operands that have their corresponding bit
99
  /// set. Operands that have their bit cleared, or that don't have a
100
  /// corresponding bit in the mask don't have their dependency broken.  Note
101
  /// that Mask may not be big enough to describe all operands.  The assumption
102
  /// for operands that don't have a correspondent bit in the mask is that those
103
  /// are still data dependent.
104
  /// 
105
  /// The only exception to the rule is for when Mask has all zeroes.
106
  /// A zero mask means: dependencies are broken for all explicit register
107
  /// operands.
108
  virtual bool isZeroIdiom(const MCInst &MI, APInt &Mask,
109
140
                           unsigned CPUID) const {
110
140
    return false;
111
140
  }
112
113
  /// Returns true if MI is a dependency breaking instruction for the
114
  /// subtarget associated with CPUID .
115
  ///
116
  /// The value computed by a dependency breaking instruction is not dependent
117
  /// on the inputs. An example of dependency breaking instruction on X86 is
118
  /// `XOR %eax, %eax`.
119
  ///
120
  /// If MI is a dependency breaking instruction for subtarget CPUID, then Mask
121
  /// can be inspected to identify independent operands.
122
  ///
123
  /// Essentially, each bit of the mask corresponds to an input operand.
124
  /// Explicit operands are laid out first in the mask; implicit operands follow
125
  /// explicit operands. Bits are set for operands that are independent.
126
  ///
127
  /// Note that the number of bits in Mask may not be equivalent to the sum of
128
  /// explicit and implicit operands in MI. Operands that don't have a
129
  /// corresponding bit in Mask are assumed "not independente".
130
  ///
131
  /// The only exception is for when Mask is all zeroes. That means: explicit
132
  /// input operands of MI are independent.
133
  virtual bool isDependencyBreaking(const MCInst &MI, APInt &Mask,
134
70
                                    unsigned CPUID) const {
135
70
    return isZeroIdiom(MI, Mask, CPUID);
136
70
  }
137
138
  /// Returns true if MI is a candidate for move elimination.
139
  ///
140
  /// Different subtargets may apply different constraints to optimizable
141
  /// register moves. For example, on most X86 subtargets, a candidate for move
142
  /// elimination cannot specify the same register for both source and
143
  /// destination.
144
  virtual bool isOptimizableRegisterMove(const MCInst &MI,
145
70
                                         unsigned CPUID) const {
146
70
    return false;
147
70
  }
148
149
  /// Given a branch instruction try to get the address the branch
150
  /// targets. Return true on success, and the address in Target.
151
  virtual bool
152
  evaluateBranch(const MCInst &Inst, uint64_t Addr, uint64_t Size,
153
                 uint64_t &Target) const;
154
155
  /// Returns (PLT virtual address, GOT virtual address) pairs for PLT entries.
156
  virtual std::vector<std::pair<uint64_t, uint64_t>>
157
  findPltEntries(uint64_t PltSectionVA, ArrayRef<uint8_t> PltContents,
158
0
                 uint64_t GotPltSectionVA, const Triple &TargetTriple) const {
159
0
    return {};
160
0
  }
161
};
162
163
} // end namespace llvm
164
165
#endif // LLVM_MC_MCINSTRANALYSIS_H