LLVM 20.0.0git
InlineAsm.h
Go to the documentation of this file.
1//===- llvm/InlineAsm.h - Class to represent inline asm strings -*- 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 class represents the inline asm strings, which are Value*'s that are
10// used as the callee operand of call instructions. InlineAsm's are uniqued
11// like constants, and created via InlineAsm::get(...).
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_IR_INLINEASM_H
16#define LLVM_IR_INLINEASM_H
17
18#include "llvm/ADT/Bitfields.h"
20#include "llvm/ADT/StringRef.h"
21#include "llvm/IR/Value.h"
23#include <cassert>
24#include <string>
25#include <vector>
26
27namespace llvm {
28
29class Error;
30class FunctionType;
31class PointerType;
32template <class ConstantClass> class ConstantUniqueMap;
33
34class InlineAsm final : public Value {
35public:
39 };
40
41private:
42 friend struct InlineAsmKeyType;
43 friend class ConstantUniqueMap<InlineAsm>;
44
45 std::string AsmString, Constraints;
46 FunctionType *FTy;
47 bool HasSideEffects;
48 bool IsAlignStack;
49 AsmDialect Dialect;
50 bool CanThrow;
51
52 InlineAsm(FunctionType *Ty, const std::string &AsmString,
53 const std::string &Constraints, bool hasSideEffects,
54 bool isAlignStack, AsmDialect asmDialect, bool canThrow);
55
56 /// When the ConstantUniqueMap merges two types and makes two InlineAsms
57 /// identical, it destroys one of them with this method.
58 void destroyConstant();
59
60public:
61 InlineAsm(const InlineAsm &) = delete;
62 InlineAsm &operator=(const InlineAsm &) = delete;
63
64 /// InlineAsm::get - Return the specified uniqued inline asm string.
65 ///
66 static InlineAsm *get(FunctionType *Ty, StringRef AsmString,
67 StringRef Constraints, bool hasSideEffects,
68 bool isAlignStack = false,
69 AsmDialect asmDialect = AD_ATT, bool canThrow = false);
70
71 bool hasSideEffects() const { return HasSideEffects; }
72 bool isAlignStack() const { return IsAlignStack; }
73 AsmDialect getDialect() const { return Dialect; }
74 bool canThrow() const { return CanThrow; }
75
76 /// getType - InlineAsm's are always pointers.
77 ///
79 return reinterpret_cast<PointerType*>(Value::getType());
80 }
81
82 /// getFunctionType - InlineAsm's are always pointers to functions.
83 ///
85
86 const std::string &getAsmString() const { return AsmString; }
87 const std::string &getConstraintString() const { return Constraints; }
88 void collectAsmStrs(SmallVectorImpl<StringRef> &AsmStrs) const;
89
90 /// This static method can be used by the parser to check to see if the
91 /// specified constraint string is legal for the type.
92 static Error verify(FunctionType *Ty, StringRef Constraints);
93
94 // Constraint String Parsing
96 isInput, // 'x'
97 isOutput, // '=x'
98 isClobber, // '~x'
99 isLabel, // '!x'
100 };
101
102 using ConstraintCodeVector = std::vector<std::string>;
103
105 /// MatchingInput - If this is not -1, this is an output constraint where an
106 /// input constraint is required to match it (e.g. "0"). The value is the
107 /// constraint number that matches this one (for example, if this is
108 /// constraint #0 and constraint #4 has the value "0", this will be 4).
110
111 /// Code - The constraint code, either the register name (in braces) or the
112 /// constraint letter/number.
114
115 /// Default constructor.
116 SubConstraintInfo() = default;
117 };
118
119 using SubConstraintInfoVector = std::vector<SubConstraintInfo>;
120 struct ConstraintInfo;
121 using ConstraintInfoVector = std::vector<ConstraintInfo>;
122
124 /// Type - The basic type of the constraint: input/output/clobber/label
125 ///
127
128 /// isEarlyClobber - "&": output operand writes result before inputs are all
129 /// read. This is only ever set for an output operand.
130 bool isEarlyClobber = false;
131
132 /// MatchingInput - If this is not -1, this is an output constraint where an
133 /// input constraint is required to match it (e.g. "0"). The value is the
134 /// constraint number that matches this one (for example, if this is
135 /// constraint #0 and constraint #4 has the value "0", this will be 4).
137
138 /// hasMatchingInput - Return true if this is an output constraint that has
139 /// a matching input constraint.
140 bool hasMatchingInput() const { return MatchingInput != -1; }
141
142 /// isCommutative - This is set to true for a constraint that is commutative
143 /// with the next operand.
144 bool isCommutative = false;
145
146 /// isIndirect - True if this operand is an indirect operand. This means
147 /// that the address of the source or destination is present in the call
148 /// instruction, instead of it being returned or passed in explicitly. This
149 /// is represented with a '*' in the asm string.
150 bool isIndirect = false;
151
152 /// Code - The constraint code, either the register name (in braces) or the
153 /// constraint letter/number.
155
156 /// isMultipleAlternative - '|': has multiple-alternative constraints.
158
159 /// multipleAlternatives - If there are multiple alternative constraints,
160 /// this array will contain them. Otherwise it will be empty.
162
163 /// The currently selected alternative constraint index.
165
166 /// Default constructor.
167 ConstraintInfo() = default;
168
169 /// Parse - Analyze the specified string (e.g. "=*&{eax}") and fill in the
170 /// fields in this structure. If the constraint string is not understood,
171 /// return true, otherwise return false.
172 bool Parse(StringRef Str, ConstraintInfoVector &ConstraintsSoFar);
173
174 /// selectAlternative - Point this constraint to the alternative constraint
175 /// indicated by the index.
176 void selectAlternative(unsigned index);
177
178 /// Whether this constraint corresponds to an argument.
179 bool hasArg() const {
180 return Type == isInput || (Type == isOutput && isIndirect);
181 }
182 };
183
184 /// ParseConstraints - Split up the constraint string into the specific
185 /// constraints and their prefixes. If this returns an empty vector, and if
186 /// the constraint string itself isn't empty, there was an error parsing.
187 static ConstraintInfoVector ParseConstraints(StringRef ConstraintString);
188
189 /// ParseConstraints - Parse the constraints of this inlineasm object,
190 /// returning them the same way that ParseConstraints(str) does.
192 return ParseConstraints(Constraints);
193 }
194
195 // Methods for support type inquiry through isa, cast, and dyn_cast:
196 static bool classof(const Value *V) {
197 return V->getValueID() == Value::InlineAsmVal;
198 }
199
200 enum : uint32_t {
201 // Fixed operands on an INLINEASM SDNode.
205 Op_ExtraInfo = 3, // HasSideEffects, IsAlignStack, AsmDialect.
207
208 // Fixed operands on an INLINEASM MachineInstr.
210 MIOp_ExtraInfo = 1, // HasSideEffects, IsAlignStack, AsmDialect.
212
213 // Interpretation of the MIOp_ExtraInfo bit field.
220 };
221
222 // Inline asm operands map to multiple SDNode / MachineInstr operands.
223 // The first operand is an immediate describing the asm operand, the low
224 // bits is the kind:
225 enum class Kind : uint8_t {
226 RegUse = 1, // Input register, "r".
227 RegDef = 2, // Output register, "=r".
228 RegDefEarlyClobber = 3, // Early-clobber output register, "=&r".
229 Clobber = 4, // Clobbered register, "~r".
230 Imm = 5, // Immediate.
231 Mem = 6, // Memory operand, "m", or an address, "p".
232 Func = 7, // Address operand of function call
233 };
234
235 // Memory constraint codes.
236 // Addresses are included here as they need to be treated the same by the
237 // backend, the only difference is that they are not used to actaully
238 // access memory by the instruction.
240 Unknown = 0,
241 es,
242 i,
243 k,
244 m,
245 o,
246 v,
247 A,
248 Q,
249 R,
250 S,
251 T,
252 Um,
253 Un,
254 Uq,
255 Us,
256 Ut,
257 Uv,
258 Uy,
259 X,
260 Z,
261 ZB,
262 ZC,
263 Zy,
264
265 // Address constraints
266 p,
267 ZQ,
268 ZR,
269 ZS,
270 ZT,
271
272 Max = ZT,
273 };
274
275 // This class is intentionally packed into a 32b value as it is used as a
276 // MVT::i32 ConstantSDNode SDValue for SelectionDAG and as immediate operands
277 // on INLINEASM and INLINEASM_BR MachineInstr's.
278 //
279 // The encoding of Flag is currently:
280 // Bits 2-0 - A Kind::* value indicating the kind of the operand.
281 // (KindField)
282 // Bits 15-3 - The number of SDNode operands associated with this inline
283 // assembly operand. Once lowered to MIR, this represents the
284 // number of MachineOperands necessary to refer to a
285 // MachineOperandType::MO_FrameIndex. (NumOperands)
286 // Bit 31 - Determines if this is a matched operand. (IsMatched)
287 // If bit 31 is set:
288 // Bits 30-16 - The operand number that this operand must match.
289 // (MatchedOperandNo)
290 // Else if bits 2-0 are Kind::Mem:
291 // Bits 30-16 - A ConstraintCode:: value indicating the original
292 // constraint code. (MemConstraintCode)
293 // Else:
294 // Bits 29-16 - The register class ID to use for the operand. (RegClass)
295 // Bit 30 - If the register is permitted to be spilled.
296 // (RegMayBeFolded)
297 // Defaults to false "r", may be set for constraints like
298 // "rm" (or "g").
299 //
300 // As such, MatchedOperandNo, MemConstraintCode, and
301 // (RegClass+RegMayBeFolded) are views of the same slice of bits, but are
302 // mutually exclusive depending on the fields IsMatched then KindField.
303 class Flag {
304 uint32_t Storage;
312
313
314 unsigned getMatchedOperandNo() const { return Bitfield::get<MatchedOperandNo>(Storage); }
315 unsigned getRegClass() const { return Bitfield::get<RegClass>(Storage); }
316 bool isMatched() const { return Bitfield::get<IsMatched>(Storage); }
317
318 public:
319 Flag() : Storage(0) {}
320 explicit Flag(uint32_t F) : Storage(F) {}
321 Flag(enum Kind K, unsigned NumOps) : Storage(0) {
322 Bitfield::set<KindField>(Storage, K);
323 Bitfield::set<NumOperands>(Storage, NumOps);
324 }
325 operator uint32_t() { return Storage; }
326 Kind getKind() const { return Bitfield::get<KindField>(Storage); }
327 bool isRegUseKind() const { return getKind() == Kind::RegUse; }
328 bool isRegDefKind() const { return getKind() == Kind::RegDef; }
331 }
332 bool isClobberKind() const { return getKind() == Kind::Clobber; }
333 bool isImmKind() const { return getKind() == Kind::Imm; }
334 bool isMemKind() const { return getKind() == Kind::Mem; }
335 bool isFuncKind() const { return getKind() == Kind::Func; }
337 switch (getKind()) {
338 case Kind::RegUse:
339 return "reguse";
340 case Kind::RegDef:
341 return "regdef";
343 return "regdef-ec";
344 case Kind::Clobber:
345 return "clobber";
346 case Kind::Imm:
347 return "imm";
348 case Kind::Mem:
349 case Kind::Func:
350 return "mem";
351 }
352 llvm_unreachable("impossible kind");
353 }
354
355 /// getNumOperandRegisters - Extract the number of registers field from the
356 /// inline asm operand flag.
357 unsigned getNumOperandRegisters() const {
358 return Bitfield::get<NumOperands>(Storage);
359 }
360
361 /// isUseOperandTiedToDef - Return true if the flag of the inline asm
362 /// operand indicates it is an use operand that's matched to a def operand.
363 bool isUseOperandTiedToDef(unsigned &Idx) const {
364 if (!isMatched())
365 return false;
366 Idx = getMatchedOperandNo();
367 return true;
368 }
369
370 /// hasRegClassConstraint - Returns true if the flag contains a register
371 /// class constraint. Sets RC to the register class ID.
372 bool hasRegClassConstraint(unsigned &RC) const {
373 if (isMatched())
374 return false;
375 // setRegClass() uses 0 to mean no register class, and otherwise stores
376 // RC + 1.
377 if (!getRegClass())
378 return false;
379 RC = getRegClass() - 1;
380 return true;
381 }
382
384 assert((isMemKind() || isFuncKind()) &&
385 "Not expected mem or function flag!");
386 return Bitfield::get<MemConstraintCode>(Storage);
387 }
388
389 /// setMatchingOp - Augment an existing flag with information indicating
390 /// that this input operand is tied to a previous output operand.
391 void setMatchingOp(unsigned OperandNo) {
392 assert(getMatchedOperandNo() == 0 && "Matching operand already set");
393 Bitfield::set<MatchedOperandNo>(Storage, OperandNo);
394 Bitfield::set<IsMatched>(Storage, true);
395 }
396
397 /// setRegClass - Augment an existing flag with the required register class
398 /// for the following register operands. A tied use operand cannot have a
399 /// register class, use the register class from the def operand instead.
400 void setRegClass(unsigned RC) {
401 assert(!isImmKind() && "Immediates cannot have a register class");
402 assert(!isMemKind() && "Memory operand cannot have a register class");
403 assert(getRegClass() == 0 && "Register class already set");
404 // Store RC + 1, reserve the value 0 to mean 'no register class'.
405 Bitfield::set<RegClass>(Storage, RC + 1);
406 }
407
408 /// setMemConstraint - Augment an existing flag with the constraint code for
409 /// a memory constraint.
411 assert(getMemoryConstraintID() == ConstraintCode::Unknown && "Mem constraint already set");
412 Bitfield::set<MemConstraintCode>(Storage, C);
413 }
414 /// clearMemConstraint - Similar to setMemConstraint(0), but without the
415 /// assertion checking that the constraint has not been set previously.
417 assert((isMemKind() || isFuncKind()) &&
418 "Flag is not a memory or function constraint!");
419 Bitfield::set<MemConstraintCode>(Storage, ConstraintCode::Unknown);
420 }
421
422 /// Set a bit to denote that while this operand is some kind of register
423 /// (use, def, ...), a memory flag did appear in the original constraint
424 /// list. This is set by the instruction selection framework, and consumed
425 /// by the register allocator. While the register allocator is generally
426 /// responsible for spilling registers, we need to be able to distinguish
427 /// between registers that the register allocator has permission to fold
428 /// ("rm") vs ones it does not ("r"). This is because the inline asm may use
429 /// instructions which don't support memory addressing modes for that
430 /// operand.
431 void setRegMayBeFolded(bool B) {
433 "Must be reg");
434 Bitfield::set<RegMayBeFolded>(Storage, B);
435 }
436 bool getRegMayBeFolded() const {
438 "Must be reg");
439 return Bitfield::get<RegMayBeFolded>(Storage);
440 }
441 };
442
443 static std::vector<StringRef> getExtraInfoNames(unsigned ExtraInfo) {
444 std::vector<StringRef> Result;
445 if (ExtraInfo & InlineAsm::Extra_HasSideEffects)
446 Result.push_back("sideeffect");
447 if (ExtraInfo & InlineAsm::Extra_MayLoad)
448 Result.push_back("mayload");
449 if (ExtraInfo & InlineAsm::Extra_MayStore)
450 Result.push_back("maystore");
451 if (ExtraInfo & InlineAsm::Extra_IsConvergent)
452 Result.push_back("isconvergent");
453 if (ExtraInfo & InlineAsm::Extra_IsAlignStack)
454 Result.push_back("alignstack");
455
456 AsmDialect Dialect =
458
459 if (Dialect == InlineAsm::AD_ATT)
460 Result.push_back("attdialect");
461 if (Dialect == InlineAsm::AD_Intel)
462 Result.push_back("inteldialect");
463
464 return Result;
465 }
466
468 switch (C) {
470 return "es";
472 return "i";
474 return "k";
476 return "m";
478 return "o";
480 return "v";
482 return "A";
484 return "Q";
486 return "R";
488 return "S";
490 return "T";
492 return "Um";
494 return "Un";
496 return "Uq";
498 return "Us";
500 return "Ut";
502 return "Uv";
504 return "Uy";
506 return "X";
508 return "Z";
510 return "ZB";
512 return "ZC";
514 return "Zy";
516 return "p";
518 return "ZQ";
520 return "ZR";
522 return "ZS";
524 return "ZT";
525 default:
526 llvm_unreachable("Unknown memory constraint");
527 }
528 }
529};
530
531} // end namespace llvm
532
533#endif // LLVM_IR_INLINEASM_H
This file implements methods to test, set and extract typed bits from packed unsigned integers.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
#define F(x, y, z)
Definition: MD5.cpp:55
ppc ctr loops verify
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
Lightweight error class with error context and mandatory checking.
Definition: Error.h:160
Class to represent function types.
Definition: DerivedTypes.h:105
void setRegMayBeFolded(bool B)
Set a bit to denote that while this operand is some kind of register (use, def, .....
Definition: InlineAsm.h:431
bool isImmKind() const
Definition: InlineAsm.h:333
bool isClobberKind() const
Definition: InlineAsm.h:332
void setRegClass(unsigned RC)
setRegClass - Augment an existing flag with the required register class for the following register op...
Definition: InlineAsm.h:400
StringRef getKindName() const
Definition: InlineAsm.h:336
void clearMemConstraint()
clearMemConstraint - Similar to setMemConstraint(0), but without the assertion checking that the cons...
Definition: InlineAsm.h:416
Kind getKind() const
Definition: InlineAsm.h:326
Flag(enum Kind K, unsigned NumOps)
Definition: InlineAsm.h:321
bool hasRegClassConstraint(unsigned &RC) const
hasRegClassConstraint - Returns true if the flag contains a register class constraint.
Definition: InlineAsm.h:372
bool isRegUseKind() const
Definition: InlineAsm.h:327
bool isMemKind() const
Definition: InlineAsm.h:334
void setMatchingOp(unsigned OperandNo)
setMatchingOp - Augment an existing flag with information indicating that this input operand is tied ...
Definition: InlineAsm.h:391
void setMemConstraint(ConstraintCode C)
setMemConstraint - Augment an existing flag with the constraint code for a memory constraint.
Definition: InlineAsm.h:410
ConstraintCode getMemoryConstraintID() const
Definition: InlineAsm.h:383
bool getRegMayBeFolded() const
Definition: InlineAsm.h:436
bool isUseOperandTiedToDef(unsigned &Idx) const
isUseOperandTiedToDef - Return true if the flag of the inline asm operand indicates it is an use oper...
Definition: InlineAsm.h:363
bool isFuncKind() const
Definition: InlineAsm.h:335
unsigned getNumOperandRegisters() const
getNumOperandRegisters - Extract the number of registers field from the inline asm operand flag.
Definition: InlineAsm.h:357
Flag(uint32_t F)
Definition: InlineAsm.h:320
bool isRegDefEarlyClobberKind() const
Definition: InlineAsm.h:329
bool isRegDefKind() const
Definition: InlineAsm.h:328
const std::string & getConstraintString() const
Definition: InlineAsm.h:87
void collectAsmStrs(SmallVectorImpl< StringRef > &AsmStrs) const
Definition: InlineAsm.cpp:62
const std::string & getAsmString() const
Definition: InlineAsm.h:86
static InlineAsm * get(FunctionType *Ty, StringRef AsmString, StringRef Constraints, bool hasSideEffects, bool isAlignStack=false, AsmDialect asmDialect=AD_ATT, bool canThrow=false)
InlineAsm::get - Return the specified uniqued inline asm string.
Definition: InlineAsm.cpp:43
std::vector< SubConstraintInfo > SubConstraintInfoVector
Definition: InlineAsm.h:119
std::vector< ConstraintInfo > ConstraintInfoVector
Definition: InlineAsm.h:121
static std::vector< StringRef > getExtraInfoNames(unsigned ExtraInfo)
Definition: InlineAsm.h:443
bool isAlignStack() const
Definition: InlineAsm.h:72
AsmDialect getDialect() const
Definition: InlineAsm.h:73
FunctionType * getFunctionType() const
getFunctionType - InlineAsm's are always pointers to functions.
Definition: InlineAsm.cpp:58
bool hasSideEffects() const
Definition: InlineAsm.h:71
InlineAsm(const InlineAsm &)=delete
ConstraintInfoVector ParseConstraints() const
ParseConstraints - Parse the constraints of this inlineasm object, returning them the same way that P...
Definition: InlineAsm.h:191
bool canThrow() const
Definition: InlineAsm.h:74
std::vector< std::string > ConstraintCodeVector
Definition: InlineAsm.h:102
static StringRef getMemConstraintName(ConstraintCode C)
Definition: InlineAsm.h:467
PointerType * getType() const
getType - InlineAsm's are always pointers.
Definition: InlineAsm.h:78
static bool classof(const Value *V)
Definition: InlineAsm.h:196
InlineAsm & operator=(const InlineAsm &)=delete
Class to represent pointers.
Definition: DerivedTypes.h:670
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:573
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
LLVM Value Representation.
Definition: Value.h:74
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:255
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
Describes an element of a Bitfield.
Definition: Bitfields.h:223
bool isCommutative
isCommutative - This is set to true for a constraint that is commutative with the next operand.
Definition: InlineAsm.h:144
int MatchingInput
MatchingInput - If this is not -1, this is an output constraint where an input constraint is required...
Definition: InlineAsm.h:136
ConstraintCodeVector Codes
Code - The constraint code, either the register name (in braces) or the constraint letter/number.
Definition: InlineAsm.h:154
unsigned currentAlternativeIndex
The currently selected alternative constraint index.
Definition: InlineAsm.h:164
ConstraintInfo()=default
Default constructor.
bool Parse(StringRef Str, ConstraintInfoVector &ConstraintsSoFar)
Parse - Analyze the specified string (e.g.
Definition: InlineAsm.cpp:78
bool hasArg() const
Whether this constraint corresponds to an argument.
Definition: InlineAsm.h:179
SubConstraintInfoVector multipleAlternatives
multipleAlternatives - If there are multiple alternative constraints, this array will contain them.
Definition: InlineAsm.h:161
bool isIndirect
isIndirect - True if this operand is an indirect operand.
Definition: InlineAsm.h:150
bool isEarlyClobber
isEarlyClobber - "&": output operand writes result before inputs are all read.
Definition: InlineAsm.h:130
bool isMultipleAlternative
isMultipleAlternative - '|': has multiple-alternative constraints.
Definition: InlineAsm.h:157
void selectAlternative(unsigned index)
selectAlternative - Point this constraint to the alternative constraint indicated by the index.
Definition: InlineAsm.cpp:224
bool hasMatchingInput() const
hasMatchingInput - Return true if this is an output constraint that has a matching input constraint.
Definition: InlineAsm.h:140
ConstraintCodeVector Codes
Code - The constraint code, either the register name (in braces) or the constraint letter/number.
Definition: InlineAsm.h:113
int MatchingInput
MatchingInput - If this is not -1, this is an output constraint where an input constraint is required...
Definition: InlineAsm.h:109
SubConstraintInfo()=default
Default constructor.