LLVM  8.0.1
InlineAsm.cpp
Go to the documentation of this file.
1 //===- InlineAsm.cpp - Implement the InlineAsm class ----------------------===//
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 // This file implements the InlineAsm class.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "llvm/IR/InlineAsm.h"
15 #include "ConstantsContext.h"
16 #include "LLVMContextImpl.h"
17 #include "llvm/ADT/StringRef.h"
18 #include "llvm/IR/DerivedTypes.h"
19 #include "llvm/IR/LLVMContext.h"
20 #include "llvm/IR/Value.h"
21 #include "llvm/Support/Casting.h"
22 #include "llvm/Support/Compiler.h"
23 #include <algorithm>
24 #include <cassert>
25 #include <cctype>
26 #include <cstddef>
27 #include <cstdlib>
28 
29 using namespace llvm;
30 
31 InlineAsm::InlineAsm(FunctionType *FTy, const std::string &asmString,
32  const std::string &constraints, bool hasSideEffects,
33  bool isAlignStack, AsmDialect asmDialect)
34  : Value(PointerType::getUnqual(FTy), Value::InlineAsmVal),
35  AsmString(asmString), Constraints(constraints), FTy(FTy),
36  HasSideEffects(hasSideEffects), IsAlignStack(isAlignStack),
37  Dialect(asmDialect) {
38  // Do various checks on the constraint string and type.
39  assert(Verify(getFunctionType(), constraints) &&
40  "Function type not legal for constraints!");
41 }
42 
44  StringRef Constraints, bool hasSideEffects,
45  bool isAlignStack, AsmDialect asmDialect) {
46  InlineAsmKeyType Key(AsmString, Constraints, FTy, hasSideEffects,
47  isAlignStack, asmDialect);
48  LLVMContextImpl *pImpl = FTy->getContext().pImpl;
49  return pImpl->InlineAsms.getOrCreate(PointerType::getUnqual(FTy), Key);
50 }
51 
52 void InlineAsm::destroyConstant() {
53  getType()->getContext().pImpl->InlineAsms.remove(this);
54  delete this;
55 }
56 
58  return FTy;
59 }
60 
61 /// Parse - Analyze the specified string (e.g. "==&{eax}") and fill in the
62 /// fields in this structure. If the constraint string is not understood,
63 /// return true, otherwise return false.
65  InlineAsm::ConstraintInfoVector &ConstraintsSoFar) {
66  StringRef::iterator I = Str.begin(), E = Str.end();
67  unsigned multipleAlternativeCount = Str.count('|') + 1;
68  unsigned multipleAlternativeIndex = 0;
69  ConstraintCodeVector *pCodes = &Codes;
70 
71  // Initialize
72  isMultipleAlternative = multipleAlternativeCount > 1;
73  if (isMultipleAlternative) {
74  multipleAlternatives.resize(multipleAlternativeCount);
75  pCodes = &multipleAlternatives[0].Codes;
76  }
77  Type = isInput;
78  isEarlyClobber = false;
79  MatchingInput = -1;
80  isCommutative = false;
81  isIndirect = false;
82  currentAlternativeIndex = 0;
83 
84  // Parse prefixes.
85  if (*I == '~') {
86  Type = isClobber;
87  ++I;
88 
89  // '{' must immediately follow '~'.
90  if (I != E && *I != '{')
91  return true;
92  } else if (*I == '=') {
93  ++I;
94  Type = isOutput;
95  }
96 
97  if (*I == '*') {
98  isIndirect = true;
99  ++I;
100  }
101 
102  if (I == E) return true; // Just a prefix, like "==" or "~".
103 
104  // Parse the modifiers.
105  bool DoneWithModifiers = false;
106  while (!DoneWithModifiers) {
107  switch (*I) {
108  default:
109  DoneWithModifiers = true;
110  break;
111  case '&': // Early clobber.
112  if (Type != isOutput || // Cannot early clobber anything but output.
113  isEarlyClobber) // Reject &&&&&&
114  return true;
115  isEarlyClobber = true;
116  break;
117  case '%': // Commutative.
118  if (Type == isClobber || // Cannot commute clobbers.
119  isCommutative) // Reject %%%%%
120  return true;
121  isCommutative = true;
122  break;
123  case '#': // Comment.
124  case '*': // Register preferencing.
125  return true; // Not supported.
126  }
127 
128  if (!DoneWithModifiers) {
129  ++I;
130  if (I == E) return true; // Just prefixes and modifiers!
131  }
132  }
133 
134  // Parse the various constraints.
135  while (I != E) {
136  if (*I == '{') { // Physical register reference.
137  // Find the end of the register name.
138  StringRef::iterator ConstraintEnd = std::find(I+1, E, '}');
139  if (ConstraintEnd == E) return true; // "{foo"
140  pCodes->push_back(StringRef(I, ConstraintEnd+1 - I));
141  I = ConstraintEnd+1;
142  } else if (isdigit(static_cast<unsigned char>(*I))) { // Matching Constraint
143  // Maximal munch numbers.
144  StringRef::iterator NumStart = I;
145  while (I != E && isdigit(static_cast<unsigned char>(*I)))
146  ++I;
147  pCodes->push_back(StringRef(NumStart, I - NumStart));
148  unsigned N = atoi(pCodes->back().c_str());
149  // Check that this is a valid matching constraint!
150  if (N >= ConstraintsSoFar.size() || ConstraintsSoFar[N].Type != isOutput||
151  Type != isInput)
152  return true; // Invalid constraint number.
153 
154  // If Operand N already has a matching input, reject this. An output
155  // can't be constrained to the same value as multiple inputs.
156  if (isMultipleAlternative) {
157  if (multipleAlternativeIndex >=
158  ConstraintsSoFar[N].multipleAlternatives.size())
159  return true;
161  ConstraintsSoFar[N].multipleAlternatives[multipleAlternativeIndex];
162  if (scInfo.MatchingInput != -1)
163  return true;
164  // Note that operand #n has a matching input.
165  scInfo.MatchingInput = ConstraintsSoFar.size();
166  assert(scInfo.MatchingInput >= 0);
167  } else {
168  if (ConstraintsSoFar[N].hasMatchingInput() &&
169  (size_t)ConstraintsSoFar[N].MatchingInput !=
170  ConstraintsSoFar.size())
171  return true;
172  // Note that operand #n has a matching input.
173  ConstraintsSoFar[N].MatchingInput = ConstraintsSoFar.size();
174  assert(ConstraintsSoFar[N].MatchingInput >= 0);
175  }
176  } else if (*I == '|') {
177  multipleAlternativeIndex++;
178  pCodes = &multipleAlternatives[multipleAlternativeIndex].Codes;
179  ++I;
180  } else if (*I == '^') {
181  // Multi-letter constraint
182  // FIXME: For now assuming these are 2-character constraints.
183  pCodes->push_back(StringRef(I+1, 2));
184  I += 3;
185  } else {
186  // Single letter constraint.
187  pCodes->push_back(StringRef(I, 1));
188  ++I;
189  }
190  }
191 
192  return false;
193 }
194 
195 /// selectAlternative - Point this constraint to the alternative constraint
196 /// indicated by the index.
198  if (index < multipleAlternatives.size()) {
199  currentAlternativeIndex = index;
201  multipleAlternatives[currentAlternativeIndex];
202  MatchingInput = scInfo.MatchingInput;
203  Codes = scInfo.Codes;
204  }
205 }
206 
209  ConstraintInfoVector Result;
210 
211  // Scan the constraints string.
212  for (StringRef::iterator I = Constraints.begin(),
213  E = Constraints.end(); I != E; ) {
215 
216  // Find the end of this constraint.
217  StringRef::iterator ConstraintEnd = std::find(I, E, ',');
218 
219  if (ConstraintEnd == I || // Empty constraint like ",,"
220  Info.Parse(StringRef(I, ConstraintEnd-I), Result)) {
221  Result.clear(); // Erroneous constraint?
222  break;
223  }
224 
225  Result.push_back(Info);
226 
227  // ConstraintEnd may be either the next comma or the end of the string. In
228  // the former case, we skip the comma.
229  I = ConstraintEnd;
230  if (I != E) {
231  ++I;
232  if (I == E) {
233  Result.clear();
234  break;
235  } // don't allow "xyz,"
236  }
237  }
238 
239  return Result;
240 }
241 
242 /// Verify - Verify that the specified constraint string is reasonable for the
243 /// specified function type, and otherwise validate the constraint string.
245  if (Ty->isVarArg()) return false;
246 
247  ConstraintInfoVector Constraints = ParseConstraints(ConstStr);
248 
249  // Error parsing constraints.
250  if (Constraints.empty() && !ConstStr.empty()) return false;
251 
252  unsigned NumOutputs = 0, NumInputs = 0, NumClobbers = 0;
253  unsigned NumIndirect = 0;
254 
255  for (unsigned i = 0, e = Constraints.size(); i != e; ++i) {
256  switch (Constraints[i].Type) {
257  case InlineAsm::isOutput:
258  if ((NumInputs-NumIndirect) != 0 || NumClobbers != 0)
259  return false; // outputs before inputs and clobbers.
260  if (!Constraints[i].isIndirect) {
261  ++NumOutputs;
262  break;
263  }
264  ++NumIndirect;
265  LLVM_FALLTHROUGH; // We fall through for Indirect Outputs.
266  case InlineAsm::isInput:
267  if (NumClobbers) return false; // inputs before clobbers.
268  ++NumInputs;
269  break;
271  ++NumClobbers;
272  break;
273  }
274  }
275 
276  switch (NumOutputs) {
277  case 0:
278  if (!Ty->getReturnType()->isVoidTy()) return false;
279  break;
280  case 1:
281  if (Ty->getReturnType()->isStructTy()) return false;
282  break;
283  default:
285  if (!STy || STy->getNumElements() != NumOutputs)
286  return false;
287  break;
288  }
289 
290  if (Ty->getNumParams() != NumInputs) return false;
291  return true;
292 }
This class represents lattice values for constants.
Definition: AllocatorList.h:24
#define LLVM_FALLTHROUGH
Definition: Compiler.h:86
unsigned getNumElements() const
Random access to the elements.
Definition: DerivedTypes.h:313
bool Parse(StringRef Str, ConstraintInfoVector &ConstraintsSoFar)
Parse - Analyze the specified string (e.g.
Definition: InlineAsm.cpp:64
LLVMContext & getContext() const
Return the LLVMContext in which this type was uniqued.
Definition: Type.h:130
std::vector< std::string > ConstraintCodeVector
Definition: InlineAsm.h:97
LLVM_NODISCARD size_t count(char C) const
Return the number of occurrences of C in the string.
Definition: StringRef.h:476
Class to represent struct types.
Definition: DerivedTypes.h:201
ConstantUniqueMap< InlineAsm > InlineAsms
Key
PAL metadata keys.
Class to represent function types.
Definition: DerivedTypes.h:103
ppc ctr loops PowerPC CTR Loops Verify
bool isVarArg() const
Definition: DerivedTypes.h:123
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:133
static bool Verify(FunctionType *Ty, StringRef Constraints)
Verify - This static method can be used by the parser to check to see if the specified constraint str...
Definition: InlineAsm.cpp:244
Analysis containing CSE Info
Definition: CSEInfo.cpp:21
Class to represent pointers.
Definition: DerivedTypes.h:467
bool isVoidTy() const
Return true if this is &#39;void&#39;.
Definition: Type.h:141
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:46
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
Definition: DerivedTypes.h:139
static wasm::ValType getType(const TargetRegisterClass *RC)
auto find(R &&Range, const T &Val) -> decltype(adl_begin(Range))
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:1207
LLVMContextImpl *const pImpl
Definition: LLVMContext.h:71
std::vector< ConstraintInfo > ConstraintInfoVector
Definition: InlineAsm.h:116
ConstraintCodeVector Codes
Code - The constraint code, either the register name (in braces) or the constraint letter/number...
Definition: InlineAsm.h:108
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the generic address space (address sp...
Definition: DerivedTypes.h:482
Type * getReturnType() const
Definition: DerivedTypes.h:124
iterator begin() const
Definition: StringRef.h:106
#define I(x, y, z)
Definition: MD5.cpp:58
#define N
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Definition: Casting.h:323
FunctionType * getFunctionType() const
getFunctionType - InlineAsm&#39;s are always pointers to functions.
Definition: InlineAsm.cpp:57
static InlineAsm * get(FunctionType *Ty, StringRef AsmString, StringRef Constraints, bool hasSideEffects, bool isAlignStack=false, AsmDialect asmDialect=AD_ATT)
InlineAsm::get - Return the specified uniqued inline asm string.
Definition: InlineAsm.cpp:43
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool isInput(const StringSet<> &Prefixes, StringRef Arg)
Definition: OptTable.cpp:170
LLVM Value Representation.
Definition: Value.h:73
int MatchingInput
MatchingInput - If this is not -1, this is an output constraint where an input constraint is required...
Definition: InlineAsm.h:104
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
iterator end() const
Definition: StringRef.h:108
ConstraintInfoVector ParseConstraints() const
ParseConstraints - Parse the constraints of this inlineasm object, returning them the same way that P...
Definition: InlineAsm.h:181
bool isStructTy() const
True if this is an instance of StructType.
Definition: Type.h:218
void selectAlternative(unsigned index)
selectAlternative - Point this constraint to the alternative constraint indicated by the index...
Definition: InlineAsm.cpp:197