LLVM  4.0.0
HexagonGenExtract.cpp
Go to the documentation of this file.
1 //===--- HexagonGenExtract.cpp --------------------------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "llvm/ADT/APInt.h"
11 #include "llvm/ADT/StringRef.h"
12 #include "llvm/IR/BasicBlock.h"
13 #include "llvm/IR/CFG.h"
14 #include "llvm/IR/Constants.h"
15 #include "llvm/IR/Dominators.h"
16 #include "llvm/IR/Function.h"
17 #include "llvm/IR/Instruction.h"
18 #include "llvm/IR/Instructions.h"
19 #include "llvm/IR/Intrinsics.h"
20 #include "llvm/IR/IRBuilder.h"
21 #include "llvm/IR/PatternMatch.h"
22 #include "llvm/IR/Type.h"
23 #include "llvm/IR/Value.h"
24 #include "llvm/Pass.h"
26 #include <algorithm>
27 #include <cstdint>
28 #include <iterator>
29 
30 using namespace llvm;
31 
32 static cl::opt<unsigned> ExtractCutoff("extract-cutoff", cl::init(~0U),
33  cl::Hidden, cl::desc("Cutoff for generating \"extract\""
34  " instructions"));
35 
36 // This prevents generating extract instructions that have the offset of 0.
37 // One of the reasons for "extract" is to put a sequence of bits in a regis-
38 // ter, starting at offset 0 (so that these bits can then be used by an
39 // "insert"). If the bits are already at offset 0, it is better not to gene-
40 // rate "extract", since logical bit operations can be merged into compound
41 // instructions (as opposed to "extract").
42 static cl::opt<bool> NoSR0("extract-nosr0", cl::init(true), cl::Hidden,
43  cl::desc("No extract instruction with offset 0"));
44 
45 static cl::opt<bool> NeedAnd("extract-needand", cl::init(true), cl::Hidden,
46  cl::desc("Require & in extract patterns"));
47 
48 namespace llvm {
49 
52 
53 } // end namespace llvm
54 
55 namespace {
56 
57  class HexagonGenExtract : public FunctionPass {
58  public:
59  static char ID;
60 
61  HexagonGenExtract() : FunctionPass(ID), ExtractCount(0) {
63  }
64 
65  StringRef getPassName() const override {
66  return "Hexagon generate \"extract\" instructions";
67  }
68 
69  bool runOnFunction(Function &F) override;
70 
71  void getAnalysisUsage(AnalysisUsage &AU) const override {
75  }
76 
77  private:
78  bool visitBlock(BasicBlock *B);
79  bool convert(Instruction *In);
80 
81  unsigned ExtractCount;
82  DominatorTree *DT;
83  };
84 
85  char HexagonGenExtract::ID = 0;
86 
87 } // end anonymous namespace
88 
89 INITIALIZE_PASS_BEGIN(HexagonGenExtract, "hextract", "Hexagon generate "
90  "\"extract\" instructions", false, false)
92 INITIALIZE_PASS_END(HexagonGenExtract, "hextract", "Hexagon generate "
93  "\"extract\" instructions", false, false)
94 
95 bool HexagonGenExtract::convert(Instruction *In) {
96  using namespace PatternMatch;
97 
98  Value *BF = nullptr;
99  ConstantInt *CSL = nullptr, *CSR = nullptr, *CM = nullptr;
100  BasicBlock *BB = In->getParent();
101  LLVMContext &Ctx = BB->getContext();
102  bool LogicalSR;
103 
104  // (and (shl (lshr x, #sr), #sl), #m)
105  LogicalSR = true;
106  bool Match = match(In, m_And(m_Shl(m_LShr(m_Value(BF), m_ConstantInt(CSR)),
107  m_ConstantInt(CSL)),
108  m_ConstantInt(CM)));
109 
110  if (!Match) {
111  // (and (shl (ashr x, #sr), #sl), #m)
112  LogicalSR = false;
113  Match = match(In, m_And(m_Shl(m_AShr(m_Value(BF), m_ConstantInt(CSR)),
114  m_ConstantInt(CSL)),
115  m_ConstantInt(CM)));
116  }
117  if (!Match) {
118  // (and (shl x, #sl), #m)
119  LogicalSR = true;
120  CSR = ConstantInt::get(Type::getInt32Ty(Ctx), 0);
121  Match = match(In, m_And(m_Shl(m_Value(BF), m_ConstantInt(CSL)),
122  m_ConstantInt(CM)));
123  if (Match && NoSR0)
124  return false;
125  }
126  if (!Match) {
127  // (and (lshr x, #sr), #m)
128  LogicalSR = true;
129  CSL = ConstantInt::get(Type::getInt32Ty(Ctx), 0);
130  Match = match(In, m_And(m_LShr(m_Value(BF), m_ConstantInt(CSR)),
131  m_ConstantInt(CM)));
132  }
133  if (!Match) {
134  // (and (ashr x, #sr), #m)
135  LogicalSR = false;
136  CSL = ConstantInt::get(Type::getInt32Ty(Ctx), 0);
137  Match = match(In, m_And(m_AShr(m_Value(BF), m_ConstantInt(CSR)),
138  m_ConstantInt(CM)));
139  }
140  if (!Match) {
141  CM = nullptr;
142  // (shl (lshr x, #sr), #sl)
143  LogicalSR = true;
144  Match = match(In, m_Shl(m_LShr(m_Value(BF), m_ConstantInt(CSR)),
145  m_ConstantInt(CSL)));
146  }
147  if (!Match) {
148  CM = nullptr;
149  // (shl (ashr x, #sr), #sl)
150  LogicalSR = false;
151  Match = match(In, m_Shl(m_AShr(m_Value(BF), m_ConstantInt(CSR)),
152  m_ConstantInt(CSL)));
153  }
154  if (!Match)
155  return false;
156 
157  Type *Ty = BF->getType();
158  if (!Ty->isIntegerTy())
159  return false;
160  unsigned BW = Ty->getPrimitiveSizeInBits();
161  if (BW != 32 && BW != 64)
162  return false;
163 
164  uint32_t SR = CSR->getZExtValue();
165  uint32_t SL = CSL->getZExtValue();
166 
167  if (!CM) {
168  // If there was no and, and the shift left did not remove all potential
169  // sign bits created by the shift right, then extractu cannot reproduce
170  // this value.
171  if (!LogicalSR && (SR > SL))
172  return false;
173  APInt A = APInt(BW, ~0ULL).lshr(SR).shl(SL);
174  CM = ConstantInt::get(Ctx, A);
175  }
176 
177  // CM is the shifted-left mask. Shift it back right to remove the zero
178  // bits on least-significant positions.
179  APInt M = CM->getValue().lshr(SL);
180  uint32_t T = M.countTrailingOnes();
181 
182  // During the shifts some of the bits will be lost. Calculate how many
183  // of the original value will remain after shift right and then left.
184  uint32_t U = BW - std::max(SL, SR);
185  // The width of the extracted field is the minimum of the original bits
186  // that remain after the shifts and the number of contiguous 1s in the mask.
187  uint32_t W = std::min(U, T);
188  if (W == 0)
189  return false;
190 
191  // Check if the extracted bits are contained within the mask that it is
192  // and-ed with. The extract operation will copy these bits, and so the
193  // mask cannot any holes in it that would clear any of the bits of the
194  // extracted field.
195  if (!LogicalSR) {
196  // If the shift right was arithmetic, it could have included some 1 bits.
197  // It is still ok to generate extract, but only if the mask eliminates
198  // those bits (i.e. M does not have any bits set beyond U).
199  APInt C = APInt::getHighBitsSet(BW, BW-U);
200  if (M.intersects(C) || !APIntOps::isMask(W, M))
201  return false;
202  } else {
203  // Check if M starts with a contiguous sequence of W times 1 bits. Get
204  // the low U bits of M (which eliminates the 0 bits shifted in on the
205  // left), and check if the result is APInt's "mask":
206  if (!APIntOps::isMask(W, M.getLoBits(U)))
207  return false;
208  }
209 
210  IRBuilder<> IRB(In);
211  Intrinsic::ID IntId = (BW == 32) ? Intrinsic::hexagon_S2_extractu
212  : Intrinsic::hexagon_S2_extractup;
213  Module *Mod = BB->getParent()->getParent();
214  Value *ExtF = Intrinsic::getDeclaration(Mod, IntId);
215  Value *NewIn = IRB.CreateCall(ExtF, {BF, IRB.getInt32(W), IRB.getInt32(SR)});
216  if (SL != 0)
217  NewIn = IRB.CreateShl(NewIn, SL, CSL->getName());
218  In->replaceAllUsesWith(NewIn);
219  return true;
220 }
221 
222 bool HexagonGenExtract::visitBlock(BasicBlock *B) {
223  // Depth-first, bottom-up traversal.
224  DomTreeNode *DTN = DT->getNode(B);
225  typedef GraphTraits<DomTreeNode*> GTN;
226  typedef GTN::ChildIteratorType Iter;
227  for (Iter I = GTN::child_begin(DTN), E = GTN::child_end(DTN); I != E; ++I)
228  visitBlock((*I)->getBlock());
229 
230  // Allow limiting the number of generated extracts for debugging purposes.
231  bool HasCutoff = ExtractCutoff.getPosition();
232  unsigned Cutoff = ExtractCutoff;
233 
234  bool Changed = false;
235  BasicBlock::iterator I = std::prev(B->end()), NextI, Begin = B->begin();
236  while (true) {
237  if (HasCutoff && (ExtractCount >= Cutoff))
238  return Changed;
239  bool Last = (I == Begin);
240  if (!Last)
241  NextI = std::prev(I);
242  Instruction *In = &*I;
243  bool Done = convert(In);
244  if (HasCutoff && Done)
245  ExtractCount++;
246  Changed |= Done;
247  if (Last)
248  break;
249  I = NextI;
250  }
251  return Changed;
252 }
253 
254 bool HexagonGenExtract::runOnFunction(Function &F) {
255  if (skipFunction(F))
256  return false;
257 
258  DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
259  bool Changed;
260 
261  // Traverse the function bottom-up, to see super-expressions before their
262  // sub-expressions.
264  Changed = visitBlock(Entry);
265 
266  return Changed;
267 }
268 
270  return new HexagonGenExtract();
271 }
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
Definition: PatternMatch.h:506
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
Definition: PatternMatch.h:64
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
static cl::opt< unsigned > ExtractCutoff("extract-cutoff", cl::init(~0U), cl::Hidden, cl::desc("Cutoff for generating \"extract\""" instructions"))
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:52
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
Definition: Pass.cpp:84
BinaryOp_match< LHS, RHS, Instruction::AShr > m_AShr(const LHS &L, const RHS &R)
Definition: PatternMatch.h:536
bool isMask(unsigned numBits, const APInt &APIVal)
Definition: APInt.h:1812
const Function * getParent() const
Return the enclosing method, or null if none.
Definition: BasicBlock.h:100
void initializeHexagonGenExtractPass(PassRegistry &)
iterator begin()
Instruction iterator methods.
Definition: BasicBlock.h:228
bool match(Val *V, const Pattern &P)
Definition: PatternMatch.h:41
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition: PassSupport.h:53
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
Definition: APInt.cpp:1122
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition: IRBuilder.h:588
This file implements a class to represent arbitrary precision integral constant values and operations...
APInt shl(unsigned shiftAmt) const
Left-shift function.
Definition: APInt.h:850
#define F(x, y, z)
Definition: MD5.cpp:51
Base class for the actual dominator tree node.
class_match< ConstantInt > m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
Definition: PatternMatch.h:75
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=None)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
Definition: Function.cpp:949
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition: Value.cpp:401
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
Definition: Dominators.h:96
Maximum length of the test input libFuzzer tries to guess a good value based on the corpus and reports it always prefer smaller inputs during the corpus shuffle When libFuzzer itself reports a bug this exit code will be used If indicates the maximal total time in seconds to run the fuzzer minimizes the provided crash input Use with etc Experimental Use value profile to guide fuzzing Number of simultaneous worker processes to run the jobs If min(jobs, NumberOfCpuCores()/2)\" is used.") FUZZER_FLAG_INT(reload
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Get a value with high bits set.
Definition: APInt.h:518
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:395
BinaryOp_match< LHS, RHS, Instruction::LShr > m_LShr(const LHS &L, const RHS &R)
Definition: PatternMatch.h:530
LLVM Basic Block Representation.
Definition: BasicBlock.h:51
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:45
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:48
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Hexagon generate extract false
Represent the analysis usage information of a pass.
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
Definition: PatternMatch.h:524
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE,"Assign register bank of generic virtual registers", false, false) RegBankSelect
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:298
Iterator for intrusive lists based on ilist_node.
This is the shared class of boolean and integer constants.
Definition: Constants.h:88
iterator end()
Definition: BasicBlock.h:230
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
Definition: IRBuilder.h:307
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
Definition: Constants.cpp:558
static GCRegistry::Add< ShadowStackGC > C("shadow-stack","Very portable GC for uncooperative code generators")
Class for arbitrary precision integers.
Definition: APInt.h:77
INITIALIZE_PASS_BEGIN(HexagonGenExtract,"hextract","Hexagon generate ""\"extract\" instructions", false, false) INITIALIZE_PASS_END(HexagonGenExtract
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition: IRBuilder.h:932
loop extract
static cl::opt< bool > NeedAnd("extract-needand", cl::init(true), cl::Hidden, cl::desc("Require & in extract patterns"))
static IntegerType * getInt32Ty(LLVMContext &C)
Definition: Type.cpp:169
#define I(x, y, z)
Definition: MD5.cpp:54
CallInst * CreateCall(Value *Callee, ArrayRef< Value * > Args=None, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition: IRBuilder.h:1579
unsigned getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
Definition: Type.cpp:108
LLVM Value Representation.
Definition: Value.h:71
FunctionPass * createHexagonGenExtract()
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:47
inst_range instructions(Function *F)
Definition: InstIterator.h:132
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
Definition: PassRegistry.h:40
Legacy analysis pass which computes a DominatorTree.
Definition: Dominators.h:217
static GCRegistry::Add< ErlangGC > A("erlang","erlang-compatible garbage collector")
static cl::opt< bool > NoSR0("extract-nosr0", cl::init(true), cl::Hidden, cl::desc("No extract instruction with offset 0"))