LLVM  3.7.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/STLExtras.h"
12 #include "llvm/IR/Constants.h"
13 #include "llvm/IR/Dominators.h"
14 #include "llvm/IR/Function.h"
15 #include "llvm/IR/Instructions.h"
16 #include "llvm/IR/IntrinsicInst.h"
17 #include "llvm/IR/IRBuilder.h"
18 #include "llvm/IR/PatternMatch.h"
19 #include "llvm/Pass.h"
21 #include "llvm/Support/Debug.h"
24 
25 using namespace llvm;
26 
27 static cl::opt<unsigned> ExtractCutoff("extract-cutoff", cl::init(~0U),
28  cl::Hidden, cl::desc("Cutoff for generating \"extract\""
29  " instructions"));
30 
31 // This prevents generating extract instructions that have the offset of 0.
32 // One of the reasons for "extract" is to put a sequence of bits in a regis-
33 // ter, starting at offset 0 (so that these bits can then be used by an
34 // "insert"). If the bits are already at offset 0, it is better not to gene-
35 // rate "extract", since logical bit operations can be merged into compound
36 // instructions (as opposed to "extract").
37 static cl::opt<bool> NoSR0("extract-nosr0", cl::init(true), cl::Hidden,
38  cl::desc("No extract instruction with offset 0"));
39 
40 static cl::opt<bool> NeedAnd("extract-needand", cl::init(true), cl::Hidden,
41  cl::desc("Require & in extract patterns"));
42 
43 namespace llvm {
46 }
47 
48 
49 namespace {
50  class HexagonGenExtract : public FunctionPass {
51  public:
52  static char ID;
53  HexagonGenExtract() : FunctionPass(ID), ExtractCount(0) {
55  }
56  virtual const char *getPassName() const override {
57  return "Hexagon generate \"extract\" instructions";
58  }
59  virtual bool runOnFunction(Function &F) override;
60  virtual void getAnalysisUsage(AnalysisUsage &AU) const override {
65  }
66  private:
67  bool visitBlock(BasicBlock *B);
68  bool convert(Instruction *In);
69 
70  unsigned ExtractCount;
71  DominatorTree *DT;
72  };
73 
74  char HexagonGenExtract::ID = 0;
75 }
76 
77 INITIALIZE_PASS_BEGIN(HexagonGenExtract, "hextract", "Hexagon generate "
78  "\"extract\" instructions", false, false)
80 INITIALIZE_PASS_END(HexagonGenExtract, "hextract", "Hexagon generate "
81  "\"extract\" instructions", false, false)
82 
83 
84 bool HexagonGenExtract::convert(Instruction *In) {
85  using namespace PatternMatch;
86  Value *BF = 0;
87  ConstantInt *CSL = 0, *CSR = 0, *CM = 0;
88  BasicBlock *BB = In->getParent();
89  LLVMContext &Ctx = BB->getContext();
90  bool LogicalSR;
91 
92  // (and (shl (lshr x, #sr), #sl), #m)
93  LogicalSR = true;
94  bool Match = match(In, m_And(m_Shl(m_LShr(m_Value(BF), m_ConstantInt(CSR)),
95  m_ConstantInt(CSL)),
96  m_ConstantInt(CM)));
97 
98  if (!Match) {
99  // (and (shl (ashr x, #sr), #sl), #m)
100  LogicalSR = false;
101  Match = match(In, m_And(m_Shl(m_AShr(m_Value(BF), m_ConstantInt(CSR)),
102  m_ConstantInt(CSL)),
103  m_ConstantInt(CM)));
104  }
105  if (!Match) {
106  // (and (shl x, #sl), #m)
107  LogicalSR = true;
108  CSR = ConstantInt::get(Type::getInt32Ty(Ctx), 0);
109  Match = match(In, m_And(m_Shl(m_Value(BF), m_ConstantInt(CSL)),
110  m_ConstantInt(CM)));
111  if (Match && NoSR0)
112  return false;
113  }
114  if (!Match) {
115  // (and (lshr x, #sr), #m)
116  LogicalSR = true;
117  CSL = ConstantInt::get(Type::getInt32Ty(Ctx), 0);
118  Match = match(In, m_And(m_LShr(m_Value(BF), m_ConstantInt(CSR)),
119  m_ConstantInt(CM)));
120  }
121  if (!Match) {
122  // (and (ashr x, #sr), #m)
123  LogicalSR = false;
124  CSL = ConstantInt::get(Type::getInt32Ty(Ctx), 0);
125  Match = match(In, m_And(m_AShr(m_Value(BF), m_ConstantInt(CSR)),
126  m_ConstantInt(CM)));
127  }
128  if (!Match) {
129  CM = 0;
130  // (shl (lshr x, #sr), #sl)
131  LogicalSR = true;
132  Match = match(In, m_Shl(m_LShr(m_Value(BF), m_ConstantInt(CSR)),
133  m_ConstantInt(CSL)));
134  }
135  if (!Match) {
136  CM = 0;
137  // (shl (ashr x, #sr), #sl)
138  LogicalSR = false;
139  Match = match(In, m_Shl(m_AShr(m_Value(BF), m_ConstantInt(CSR)),
140  m_ConstantInt(CSL)));
141  }
142  if (!Match)
143  return false;
144 
145  Type *Ty = BF->getType();
146  if (!Ty->isIntegerTy())
147  return false;
148  unsigned BW = Ty->getPrimitiveSizeInBits();
149  if (BW != 32 && BW != 64)
150  return false;
151 
152  uint32_t SR = CSR->getZExtValue();
153  uint32_t SL = CSL->getZExtValue();
154 
155  if (!CM) {
156  // If there was no and, and the shift left did not remove all potential
157  // sign bits created by the shift right, then extractu cannot reproduce
158  // this value.
159  if (!LogicalSR && (SR > SL))
160  return false;
161  APInt A = APInt(BW, ~0ULL).lshr(SR).shl(SL);
162  CM = ConstantInt::get(Ctx, A);
163  }
164 
165  // CM is the shifted-left mask. Shift it back right to remove the zero
166  // bits on least-significant positions.
167  APInt M = CM->getValue().lshr(SL);
168  uint32_t T = M.countTrailingOnes();
169 
170  // During the shifts some of the bits will be lost. Calculate how many
171  // of the original value will remain after shift right and then left.
172  uint32_t U = BW - std::max(SL, SR);
173  // The width of the extracted field is the minimum of the original bits
174  // that remain after the shifts and the number of contiguous 1s in the mask.
175  uint32_t W = std::min(U, T);
176  if (W == 0)
177  return false;
178 
179  // Check if the extracted bits are contained within the mask that it is
180  // and-ed with. The extract operation will copy these bits, and so the
181  // mask cannot any holes in it that would clear any of the bits of the
182  // extracted field.
183  if (!LogicalSR) {
184  // If the shift right was arithmetic, it could have included some 1 bits.
185  // It is still ok to generate extract, but only if the mask eliminates
186  // those bits (i.e. M does not have any bits set beyond U).
187  APInt C = APInt::getHighBitsSet(BW, BW-U);
188  if (M.intersects(C) || !APIntOps::isMask(W, M))
189  return false;
190  } else {
191  // Check if M starts with a contiguous sequence of W times 1 bits. Get
192  // the low U bits of M (which eliminates the 0 bits shifted in on the
193  // left), and check if the result is APInt's "mask":
194  if (!APIntOps::isMask(W, M.getLoBits(U)))
195  return false;
196  }
197 
198  IRBuilder<> IRB(BB, In);
199  Intrinsic::ID IntId = (BW == 32) ? Intrinsic::hexagon_S2_extractu
200  : Intrinsic::hexagon_S2_extractup;
201  Module *Mod = BB->getParent()->getParent();
202  Value *ExtF = Intrinsic::getDeclaration(Mod, IntId);
203  Value *NewIn = IRB.CreateCall(ExtF, {BF, IRB.getInt32(W), IRB.getInt32(SR)});
204  if (SL != 0)
205  NewIn = IRB.CreateShl(NewIn, SL, CSL->getName());
206  In->replaceAllUsesWith(NewIn);
207  return true;
208 }
209 
210 
211 bool HexagonGenExtract::visitBlock(BasicBlock *B) {
212  // Depth-first, bottom-up traversal.
213  DomTreeNode *DTN = DT->getNode(B);
214  typedef GraphTraits<DomTreeNode*> GTN;
215  typedef GTN::ChildIteratorType Iter;
216  for (Iter I = GTN::child_begin(DTN), E = GTN::child_end(DTN); I != E; ++I)
217  visitBlock((*I)->getBlock());
218 
219  // Allow limiting the number of generated extracts for debugging purposes.
220  bool HasCutoff = ExtractCutoff.getPosition();
221  unsigned Cutoff = ExtractCutoff;
222 
223  bool Changed = false;
224  BasicBlock::iterator I = std::prev(B->end()), NextI, Begin = B->begin();
225  while (true) {
226  if (HasCutoff && (ExtractCount >= Cutoff))
227  return Changed;
228  bool Last = (I == Begin);
229  if (!Last)
230  NextI = std::prev(I);
231  Instruction *In = &*I;
232  bool Done = convert(In);
233  if (HasCutoff && Done)
234  ExtractCount++;
235  Changed |= Done;
236  if (Last)
237  break;
238  I = NextI;
239  }
240  return Changed;
241 }
242 
243 
244 bool HexagonGenExtract::runOnFunction(Function &F) {
245  DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
246  bool Changed;
247 
248  // Traverse the function bottom-up, to see super-expressions before their
249  // sub-expressions.
251  Changed = visitBlock(Entry);
252 
253  return Changed;
254 }
255 
256 
258  return new HexagonGenExtract();
259 }
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
Hexagon generate extract instructions
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:114
DominatorTree GraphTraits specialization so the DominatorTree can be iterable by generic graph iterat...
Definition: GraphTraits.h:27
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
Definition: Pass.cpp:78
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:1767
const Function * getParent() const
Return the enclosing method, or null if none.
Definition: BasicBlock.h:111
F(f)
void initializeHexagonGenExtractPass(PassRegistry &)
MachineFunctionAnalysis - This class is a Pass that manages a MachineFunction object.
iterator begin()
Instruction iterator methods.
Definition: BasicBlock.h:231
bool match(Val *V, const Pattern &P)
Definition: PatternMatch.h:41
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition: PassSupport.h:70
APInt LLVM_ATTRIBUTE_UNUSED_RESULT lshr(unsigned shiftAmt) const
Logical right-shift function.
Definition: APInt.cpp:1142
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:75
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition: IRBuilder.h:517
Number of individual test Apply this number of consecutive mutations to each input exit after the first new interesting input is found the minimized corpus is saved into the first input directory Number of jobs to run If min(jobs, NumberOfCpuCores()/2)\" is used.") FUZZER_FLAG_INT(reload
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:866
APInt LLVM_ATTRIBUTE_UNUSED_RESULT shl(unsigned shiftAmt) const
Left-shift function.
Definition: APInt.h:868
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition: Value.cpp:351
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
Definition: Dominators.h:67
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Get a value with high bits set.
Definition: APInt.h:513
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:325
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:65
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:41
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
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:294
CallInst * CreateCall(Value *Callee, ArrayRef< Value * > Args=None, const Twine &Name="")
Definition: IRBuilder.h:1467
This is the shared class of boolean and integer constants.
Definition: Constants.h:47
iterator end()
Definition: BasicBlock.h:233
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
Definition: IRBuilder.h:266
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:582
Class for arbitrary precision integers.
Definition: APInt.h:73
INITIALIZE_PASS_BEGIN(HexagonGenExtract,"hextract","Hexagon generate ""\"extract\" instructions", false, false) INITIALIZE_PASS_END(HexagonGenExtract
loop extract
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition: IRBuilder.h:823
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:239
#define I(x, y, z)
Definition: MD5.cpp:54
unsigned getPrimitiveSizeInBits() const LLVM_READONLY
getPrimitiveSizeInBits - Return the basic size of this type if it is a primitive type.
Definition: Type.cpp:121
LLVM Value Representation.
Definition: Value.h:69
FunctionPass * createHexagonGenExtract()
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
Definition: PassRegistry.h:41
Legacy analysis pass which computes a DominatorTree.
Definition: Dominators.h:203
static cl::opt< bool > NoSR0("extract-nosr0", cl::init(true), cl::Hidden, cl::desc("No extract instruction with offset 0"))