LLVM 17.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
19#include "llvm/ADT/StringRef.h"
20#include "llvm/IR/Value.h"
22#include <cassert>
23#include <string>
24#include <vector>
25
26namespace llvm {
27
28class Error;
29class FunctionType;
30class PointerType;
31template <class ConstantClass> class ConstantUniqueMap;
32
33class InlineAsm final : public Value {
34public:
38 };
39
40private:
41 friend struct InlineAsmKeyType;
42 friend class ConstantUniqueMap<InlineAsm>;
43
44 std::string AsmString, Constraints;
45 FunctionType *FTy;
46 bool HasSideEffects;
47 bool IsAlignStack;
48 AsmDialect Dialect;
49 bool CanThrow;
50
51 InlineAsm(FunctionType *Ty, const std::string &AsmString,
52 const std::string &Constraints, bool hasSideEffects,
53 bool isAlignStack, AsmDialect asmDialect, bool canThrow);
54
55 /// When the ConstantUniqueMap merges two types and makes two InlineAsms
56 /// identical, it destroys one of them with this method.
57 void destroyConstant();
58
59public:
60 InlineAsm(const InlineAsm &) = delete;
61 InlineAsm &operator=(const InlineAsm &) = delete;
62
63 /// InlineAsm::get - Return the specified uniqued inline asm string.
64 ///
65 static InlineAsm *get(FunctionType *Ty, StringRef AsmString,
66 StringRef Constraints, bool hasSideEffects,
67 bool isAlignStack = false,
68 AsmDialect asmDialect = AD_ATT, bool canThrow = false);
69
70 bool hasSideEffects() const { return HasSideEffects; }
71 bool isAlignStack() const { return IsAlignStack; }
72 AsmDialect getDialect() const { return Dialect; }
73 bool canThrow() const { return CanThrow; }
74
75 /// getType - InlineAsm's are always pointers.
76 ///
78 return reinterpret_cast<PointerType*>(Value::getType());
79 }
80
81 /// getFunctionType - InlineAsm's are always pointers to functions.
82 ///
84
85 const std::string &getAsmString() const { return AsmString; }
86 const std::string &getConstraintString() const { return Constraints; }
87 void collectAsmStrs(SmallVectorImpl<StringRef> &AsmStrs) const;
88
89 /// This static method can be used by the parser to check to see if the
90 /// specified constraint string is legal for the type.
91 static Error verify(FunctionType *Ty, StringRef Constraints);
92
93 // Constraint String Parsing
95 isInput, // 'x'
96 isOutput, // '=x'
97 isClobber, // '~x'
98 isLabel, // '!x'
99 };
100
101 using ConstraintCodeVector = std::vector<std::string>;
102
104 /// MatchingInput - If this is not -1, this is an output constraint where an
105 /// input constraint is required to match it (e.g. "0"). The value is the
106 /// constraint number that matches this one (for example, if this is
107 /// constraint #0 and constraint #4 has the value "0", this will be 4).
109
110 /// Code - The constraint code, either the register name (in braces) or the
111 /// constraint letter/number.
113
114 /// Default constructor.
115 SubConstraintInfo() = default;
116 };
117
118 using SubConstraintInfoVector = std::vector<SubConstraintInfo>;
119 struct ConstraintInfo;
120 using ConstraintInfoVector = std::vector<ConstraintInfo>;
121
123 /// Type - The basic type of the constraint: input/output/clobber/label
124 ///
126
127 /// isEarlyClobber - "&": output operand writes result before inputs are all
128 /// read. This is only ever set for an output operand.
129 bool isEarlyClobber = false;
130
131 /// MatchingInput - If this is not -1, this is an output constraint where an
132 /// input constraint is required to match it (e.g. "0"). The value is the
133 /// constraint number that matches this one (for example, if this is
134 /// constraint #0 and constraint #4 has the value "0", this will be 4).
136
137 /// hasMatchingInput - Return true if this is an output constraint that has
138 /// a matching input constraint.
139 bool hasMatchingInput() const { return MatchingInput != -1; }
140
141 /// isCommutative - This is set to true for a constraint that is commutative
142 /// with the next operand.
143 bool isCommutative = false;
144
145 /// isIndirect - True if this operand is an indirect operand. This means
146 /// that the address of the source or destination is present in the call
147 /// instruction, instead of it being returned or passed in explicitly. This
148 /// is represented with a '*' in the asm string.
149 bool isIndirect = false;
150
151 /// Code - The constraint code, either the register name (in braces) or the
152 /// constraint letter/number.
154
155 /// isMultipleAlternative - '|': has multiple-alternative constraints.
157
158 /// multipleAlternatives - If there are multiple alternative constraints,
159 /// this array will contain them. Otherwise it will be empty.
161
162 /// The currently selected alternative constraint index.
164
165 /// Default constructor.
166 ConstraintInfo() = default;
167
168 /// Parse - Analyze the specified string (e.g. "=*&{eax}") and fill in the
169 /// fields in this structure. If the constraint string is not understood,
170 /// return true, otherwise return false.
171 bool Parse(StringRef Str, ConstraintInfoVector &ConstraintsSoFar);
172
173 /// selectAlternative - Point this constraint to the alternative constraint
174 /// indicated by the index.
175 void selectAlternative(unsigned index);
176
177 /// Whether this constraint corresponds to an argument.
178 bool hasArg() const {
179 return Type == isInput || (Type == isOutput && isIndirect);
180 }
181 };
182
183 /// ParseConstraints - Split up the constraint string into the specific
184 /// constraints and their prefixes. If this returns an empty vector, and if
185 /// the constraint string itself isn't empty, there was an error parsing.
186 static ConstraintInfoVector ParseConstraints(StringRef ConstraintString);
187
188 /// ParseConstraints - Parse the constraints of this inlineasm object,
189 /// returning them the same way that ParseConstraints(str) does.
191 return ParseConstraints(Constraints);
192 }
193
194 // Methods for support type inquiry through isa, cast, and dyn_cast:
195 static bool classof(const Value *V) {
196 return V->getValueID() == Value::InlineAsmVal;
197 }
198
199 // These are helper methods for dealing with flags in the INLINEASM SDNode
200 // in the backend.
201 //
202 // The encoding of the flag word is currently:
203 // Bits 2-0 - A Kind_* value indicating the kind of the operand.
204 // Bits 15-3 - The number of SDNode operands associated with this inline
205 // assembly operand.
206 // If bit 31 is set:
207 // Bit 30-16 - The operand number that this operand must match.
208 // When bits 2-0 are Kind_Mem, the Constraint_* value must be
209 // obtained from the flags for this operand number.
210 // Else if bits 2-0 are Kind_Mem:
211 // Bit 30-16 - A Constraint_* value indicating the original constraint
212 // code.
213 // Else:
214 // Bit 30-16 - The register class ID to use for the operand.
215
216 enum : uint32_t {
217 // Fixed operands on an INLINEASM SDNode.
221 Op_ExtraInfo = 3, // HasSideEffects, IsAlignStack, AsmDialect.
223
224 // Fixed operands on an INLINEASM MachineInstr.
226 MIOp_ExtraInfo = 1, // HasSideEffects, IsAlignStack, AsmDialect.
228
229 // Interpretation of the MIOp_ExtraInfo bit field.
236
237 // Inline asm operands map to multiple SDNode / MachineInstr operands.
238 // The first operand is an immediate describing the asm operand, the low
239 // bits is the kind:
240 Kind_RegUse = 1, // Input register, "r".
241 Kind_RegDef = 2, // Output register, "=r".
242 Kind_RegDefEarlyClobber = 3, // Early-clobber output register, "=&r".
243 Kind_Clobber = 4, // Clobbered register, "~r".
244 Kind_Imm = 5, // Immediate.
245 Kind_Mem = 6, // Memory operand, "m", or an address, "p".
246 Kind_Func = 7, // Address operand of function call
247
248 // Memory constraint codes.
249 // These could be tablegenerated but there's little need to do that since
250 // there's plenty of space in the encoding to support the union of all
251 // constraint codes for all targets.
252 // Addresses are included here as they need to be treated the same by the
253 // backend, the only difference is that they are not used to actaully
254 // access memory by the instruction.
279
280 // Address constraints
286
289
290 Flag_MatchingOperand = 0x80000000
291 };
292
293 static unsigned getFlagWord(unsigned Kind, unsigned NumOps) {
294 assert(((NumOps << 3) & ~0xffff) == 0 && "Too many inline asm operands!");
295 assert(Kind >= Kind_RegUse && Kind <= Kind_Func && "Invalid Kind");
296 return Kind | (NumOps << 3);
297 }
298
299 static bool isRegDefKind(unsigned Flag){ return getKind(Flag) == Kind_RegDef;}
300 static bool isImmKind(unsigned Flag) { return getKind(Flag) == Kind_Imm; }
301 static bool isMemKind(unsigned Flag) { return getKind(Flag) == Kind_Mem; }
302 static bool isFuncKind(unsigned Flag) { return getKind(Flag) == Kind_Func; }
303 static bool isRegDefEarlyClobberKind(unsigned Flag) {
304 return getKind(Flag) == Kind_RegDefEarlyClobber;
305 }
306 static bool isClobberKind(unsigned Flag) {
307 return getKind(Flag) == Kind_Clobber;
308 }
309
310 /// getFlagWordForMatchingOp - Augment an existing flag word returned by
311 /// getFlagWord with information indicating that this input operand is tied
312 /// to a previous output operand.
313 static unsigned getFlagWordForMatchingOp(unsigned InputFlag,
314 unsigned MatchedOperandNo) {
315 assert(MatchedOperandNo <= 0x7fff && "Too big matched operand");
316 assert((InputFlag & ~0xffff) == 0 && "High bits already contain data");
317 return InputFlag | Flag_MatchingOperand | (MatchedOperandNo << 16);
318 }
319
320 /// getFlagWordForRegClass - Augment an existing flag word returned by
321 /// getFlagWord with the required register class for the following register
322 /// operands.
323 /// A tied use operand cannot have a register class, use the register class
324 /// from the def operand instead.
325 static unsigned getFlagWordForRegClass(unsigned InputFlag, unsigned RC) {
326 // Store RC + 1, reserve the value 0 to mean 'no register class'.
327 ++RC;
328 assert(!isImmKind(InputFlag) && "Immediates cannot have a register class");
329 assert(!isMemKind(InputFlag) && "Memory operand cannot have a register class");
330 assert(RC <= 0x7fff && "Too large register class ID");
331 assert((InputFlag & ~0xffff) == 0 && "High bits already contain data");
332 return InputFlag | (RC << 16);
333 }
334
335 /// Augment an existing flag word returned by getFlagWord with the constraint
336 /// code for a memory constraint.
337 static unsigned getFlagWordForMem(unsigned InputFlag, unsigned Constraint) {
338 assert((isMemKind(InputFlag) || isFuncKind(InputFlag)) &&
339 "InputFlag is not a memory (include function) constraint!");
340 assert(Constraint <= 0x7fff && "Too large a memory constraint ID");
341 assert(Constraint <= Constraints_Max && "Unknown constraint ID");
342 assert((InputFlag & ~0xffff) == 0 && "High bits already contain data");
343 return InputFlag | (Constraint << Constraints_ShiftAmount);
344 }
345
346 static unsigned convertMemFlagWordToMatchingFlagWord(unsigned InputFlag) {
347 assert(isMemKind(InputFlag));
348 return InputFlag & ~(0x7fff << Constraints_ShiftAmount);
349 }
350
351 static unsigned getKind(unsigned Flags) {
352 return Flags & 7;
353 }
354
355 static unsigned getMemoryConstraintID(unsigned Flag) {
356 assert((isMemKind(Flag) || isFuncKind(Flag)) &&
357 "Not expected mem or function flang!");
358 return (Flag >> Constraints_ShiftAmount) & 0x7fff;
359 }
360
361 /// getNumOperandRegisters - Extract the number of registers field from the
362 /// inline asm operand flag.
363 static unsigned getNumOperandRegisters(unsigned Flag) {
364 return (Flag & 0xffff) >> 3;
365 }
366
367 /// isUseOperandTiedToDef - Return true if the flag of the inline asm
368 /// operand indicates it is an use operand that's matched to a def operand.
369 static bool isUseOperandTiedToDef(unsigned Flag, unsigned &Idx) {
370 if ((Flag & Flag_MatchingOperand) == 0)
371 return false;
372 Idx = (Flag & ~Flag_MatchingOperand) >> 16;
373 return true;
374 }
375
376 /// hasRegClassConstraint - Returns true if the flag contains a register
377 /// class constraint. Sets RC to the register class ID.
378 static bool hasRegClassConstraint(unsigned Flag, unsigned &RC) {
379 if (Flag & Flag_MatchingOperand)
380 return false;
381 unsigned High = Flag >> 16;
382 // getFlagWordForRegClass() uses 0 to mean no register class, and otherwise
383 // stores RC + 1.
384 if (!High)
385 return false;
386 RC = High - 1;
387 return true;
388 }
389
390 static std::vector<StringRef> getExtraInfoNames(unsigned ExtraInfo) {
391 std::vector<StringRef> Result;
392 if (ExtraInfo & InlineAsm::Extra_HasSideEffects)
393 Result.push_back("sideeffect");
394 if (ExtraInfo & InlineAsm::Extra_MayLoad)
395 Result.push_back("mayload");
396 if (ExtraInfo & InlineAsm::Extra_MayStore)
397 Result.push_back("maystore");
398 if (ExtraInfo & InlineAsm::Extra_IsConvergent)
399 Result.push_back("isconvergent");
400 if (ExtraInfo & InlineAsm::Extra_IsAlignStack)
401 Result.push_back("alignstack");
402
403 AsmDialect Dialect =
405
406 if (Dialect == InlineAsm::AD_ATT)
407 Result.push_back("attdialect");
408 if (Dialect == InlineAsm::AD_Intel)
409 Result.push_back("inteldialect");
410
411 return Result;
412 }
413
414 static StringRef getKindName(unsigned Kind) {
415 switch (Kind) {
417 return "reguse";
419 return "regdef";
421 return "regdef-ec";
423 return "clobber";
425 return "imm";
428 return "mem";
429 default:
430 llvm_unreachable("Unknown operand kind");
431 }
432 }
433
434 static StringRef getMemConstraintName(unsigned Constraint) {
435 switch (Constraint) {
437 return "es";
439 return "i";
441 return "k";
443 return "m";
445 return "o";
447 return "v";
449 return "Q";
451 return "R";
453 return "S";
455 return "T";
457 return "Um";
459 return "Un";
461 return "Uq";
463 return "Us";
465 return "Ut";
467 return "Uv";
469 return "Uy";
471 return "X";
473 return "Z";
475 return "ZB";
477 return "ZC";
479 return "Zy";
481 return "p";
483 return "ZQ";
485 return "ZR";
487 return "ZS";
489 return "ZT";
490 default:
491 llvm_unreachable("Unknown memory constraint");
492 }
493 }
494};
495
496} // end namespace llvm
497
498#endif // LLVM_IR_INLINEASM_H
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
uint64_t High
ppc ctr loops verify
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
@ Flags
Definition: TextStubV5.cpp:93
Lightweight error class with error context and mandatory checking.
Definition: Error.h:156
Class to represent function types.
Definition: DerivedTypes.h:103
static bool isClobberKind(unsigned Flag)
Definition: InlineAsm.h:306
const std::string & getConstraintString() const
Definition: InlineAsm.h:86
static unsigned getFlagWord(unsigned Kind, unsigned NumOps)
Definition: InlineAsm.h:293
static bool isMemKind(unsigned Flag)
Definition: InlineAsm.h:301
static StringRef getKindName(unsigned Kind)
Definition: InlineAsm.h:414
void collectAsmStrs(SmallVectorImpl< StringRef > &AsmStrs) const
Definition: InlineAsm.cpp:62
static bool isRegDefKind(unsigned Flag)
Definition: InlineAsm.h:299
const std::string & getAsmString() const
Definition: InlineAsm.h:85
static unsigned getNumOperandRegisters(unsigned Flag)
getNumOperandRegisters - Extract the number of registers field from the inline asm operand flag.
Definition: InlineAsm.h:363
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:118
static unsigned getFlagWordForMem(unsigned InputFlag, unsigned Constraint)
Augment an existing flag word returned by getFlagWord with the constraint code for a memory constrain...
Definition: InlineAsm.h:337
static bool isFuncKind(unsigned Flag)
Definition: InlineAsm.h:302
std::vector< ConstraintInfo > ConstraintInfoVector
Definition: InlineAsm.h:120
static std::vector< StringRef > getExtraInfoNames(unsigned ExtraInfo)
Definition: InlineAsm.h:390
bool isAlignStack() const
Definition: InlineAsm.h:71
static StringRef getMemConstraintName(unsigned Constraint)
Definition: InlineAsm.h:434
AsmDialect getDialect() const
Definition: InlineAsm.h:72
static unsigned getMemoryConstraintID(unsigned Flag)
Definition: InlineAsm.h:355
@ Kind_RegDefEarlyClobber
Definition: InlineAsm.h:242
@ Constraints_ShiftAmount
Definition: InlineAsm.h:288
FunctionType * getFunctionType() const
getFunctionType - InlineAsm's are always pointers to functions.
Definition: InlineAsm.cpp:58
static bool isUseOperandTiedToDef(unsigned Flag, unsigned &Idx)
isUseOperandTiedToDef - Return true if the flag of the inline asm operand indicates it is an use oper...
Definition: InlineAsm.h:369
bool hasSideEffects() const
Definition: InlineAsm.h:70
InlineAsm(const InlineAsm &)=delete
static bool isImmKind(unsigned Flag)
Definition: InlineAsm.h:300
ConstraintInfoVector ParseConstraints() const
ParseConstraints - Parse the constraints of this inlineasm object, returning them the same way that P...
Definition: InlineAsm.h:190
bool canThrow() const
Definition: InlineAsm.h:73
static bool isRegDefEarlyClobberKind(unsigned Flag)
Definition: InlineAsm.h:303
std::vector< std::string > ConstraintCodeVector
Definition: InlineAsm.h:101
static bool hasRegClassConstraint(unsigned Flag, unsigned &RC)
hasRegClassConstraint - Returns true if the flag contains a register class constraint.
Definition: InlineAsm.h:378
static unsigned getFlagWordForMatchingOp(unsigned InputFlag, unsigned MatchedOperandNo)
getFlagWordForMatchingOp - Augment an existing flag word returned by getFlagWord with information ind...
Definition: InlineAsm.h:313
static unsigned getKind(unsigned Flags)
Definition: InlineAsm.h:351
static unsigned convertMemFlagWordToMatchingFlagWord(unsigned InputFlag)
Definition: InlineAsm.h:346
static unsigned getFlagWordForRegClass(unsigned InputFlag, unsigned RC)
getFlagWordForRegClass - Augment an existing flag word returned by getFlagWord with the required regi...
Definition: InlineAsm.h:325
PointerType * getType() const
getType - InlineAsm's are always pointers.
Definition: InlineAsm.h:77
static bool classof(const Value *V)
Definition: InlineAsm.h:195
InlineAsm & operator=(const InlineAsm &)=delete
Class to represent pointers.
Definition: DerivedTypes.h:643
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:577
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
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.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
bool isCommutative
isCommutative - This is set to true for a constraint that is commutative with the next operand.
Definition: InlineAsm.h:143
int MatchingInput
MatchingInput - If this is not -1, this is an output constraint where an input constraint is required...
Definition: InlineAsm.h:135
ConstraintCodeVector Codes
Code - The constraint code, either the register name (in braces) or the constraint letter/number.
Definition: InlineAsm.h:153
unsigned currentAlternativeIndex
The currently selected alternative constraint index.
Definition: InlineAsm.h:163
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:178
SubConstraintInfoVector multipleAlternatives
multipleAlternatives - If there are multiple alternative constraints, this array will contain them.
Definition: InlineAsm.h:160
bool isIndirect
isIndirect - True if this operand is an indirect operand.
Definition: InlineAsm.h:149
bool isEarlyClobber
isEarlyClobber - "&": output operand writes result before inputs are all read.
Definition: InlineAsm.h:129
bool isMultipleAlternative
isMultipleAlternative - '|': has multiple-alternative constraints.
Definition: InlineAsm.h:156
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:139
ConstraintCodeVector Codes
Code - The constraint code, either the register name (in braces) or the constraint letter/number.
Definition: InlineAsm.h:112
int MatchingInput
MatchingInput - If this is not -1, this is an output constraint where an input constraint is required...
Definition: InlineAsm.h:108
SubConstraintInfo()=default
Default constructor.