LLVM 22.0.0git
InlineAsmLowering.cpp
Go to the documentation of this file.
1//===-- lib/CodeGen/GlobalISel/InlineAsmLowering.cpp ----------------------===//
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/// \file
10/// This file implements the lowering from LLVM IR inline asm to MIR INLINEASM
11///
12//===----------------------------------------------------------------------===//
13
19#include "llvm/IR/Module.h"
20
21#define DEBUG_TYPE "inline-asm-lowering"
22
23using namespace llvm;
24
25void InlineAsmLowering::anchor() {}
26
27namespace {
28
29/// GISelAsmOperandInfo - This contains information for each constraint that we
30/// are lowering.
31class GISelAsmOperandInfo : public TargetLowering::AsmOperandInfo {
32public:
33 /// Regs - If this is a register or register class operand, this
34 /// contains the set of assigned registers corresponding to the operand.
36
37 explicit GISelAsmOperandInfo(const TargetLowering::AsmOperandInfo &Info)
38 : TargetLowering::AsmOperandInfo(Info) {}
39};
40
41using GISelAsmOperandInfoVector = SmallVector<GISelAsmOperandInfo, 16>;
42
43class ExtraFlags {
44 unsigned Flags = 0;
45
46public:
47 explicit ExtraFlags(const CallBase &CB) {
48 const InlineAsm *IA = cast<InlineAsm>(CB.getCalledOperand());
49 if (IA->hasSideEffects())
51 if (IA->isAlignStack())
53 if (CB.isConvergent())
55 Flags |= IA->getDialect() * InlineAsm::Extra_AsmDialect;
56 }
57
58 void update(const TargetLowering::AsmOperandInfo &OpInfo) {
59 // Ideally, we would only check against memory constraints. However, the
60 // meaning of an Other constraint can be target-specific and we can't easily
61 // reason about it. Therefore, be conservative and set MayLoad/MayStore
62 // for Other constraints as well.
65 if (OpInfo.Type == InlineAsm::isInput)
67 else if (OpInfo.Type == InlineAsm::isOutput)
69 else if (OpInfo.Type == InlineAsm::isClobber)
71 }
72 }
73
74 unsigned get() const { return Flags; }
75};
76
77} // namespace
78
79/// Assign virtual/physical registers for the specified register operand.
81 MachineIRBuilder &MIRBuilder,
82 GISelAsmOperandInfo &OpInfo,
83 GISelAsmOperandInfo &RefOpInfo) {
84
87
88 // No work to do for memory operations.
89 if (OpInfo.ConstraintType == TargetLowering::C_Memory)
90 return;
91
92 // If this is a constraint for a single physreg, or a constraint for a
93 // register class, find it.
94 Register AssignedReg;
95 const TargetRegisterClass *RC;
96 std::tie(AssignedReg, RC) = TLI.getRegForInlineAsmConstraint(
97 &TRI, RefOpInfo.ConstraintCode, RefOpInfo.ConstraintVT);
98 // RC is unset only on failure. Return immediately.
99 if (!RC)
100 return;
101
102 // No need to allocate a matching input constraint since the constraint it's
103 // matching to has already been allocated.
104 if (OpInfo.isMatchingInputConstraint())
105 return;
106
107 // Initialize NumRegs.
108 unsigned NumRegs = 1;
109 if (OpInfo.ConstraintVT != MVT::Other)
110 NumRegs =
111 TLI.getNumRegisters(MF.getFunction().getContext(), OpInfo.ConstraintVT);
112
113 // If this is a constraint for a specific physical register, but the type of
114 // the operand requires more than one register to be passed, we allocate the
115 // required amount of physical registers, starting from the selected physical
116 // register.
117 // For this, first retrieve a register iterator for the given register class
120
121 // Advance the iterator to the assigned register (if set)
122 if (AssignedReg) {
123 for (; *I != AssignedReg; ++I)
124 assert(I != RC->end() && "AssignedReg should be a member of provided RC");
125 }
126
127 // Finally, assign the registers. If the AssignedReg isn't set, create virtual
128 // registers with the provided register class
129 for (; NumRegs; --NumRegs, ++I) {
130 assert(I != RC->end() && "Ran out of registers to allocate!");
131 Register R = AssignedReg ? Register(*I) : RegInfo.createVirtualRegister(RC);
132 OpInfo.Regs.push_back(R);
133 }
134}
135
138 assert(!OpInfo.Codes.empty() && "Must have at least one constraint");
139
140 // Single-letter constraints ('r') are very common.
141 if (OpInfo.Codes.size() == 1) {
142 OpInfo.ConstraintCode = OpInfo.Codes[0];
143 OpInfo.ConstraintType = TLI->getConstraintType(OpInfo.ConstraintCode);
144 } else {
146 if (G.empty())
147 return;
148 // FIXME: prefer immediate constraints if the target allows it
149 unsigned BestIdx = 0;
150 for (const unsigned E = G.size();
151 BestIdx < E && (G[BestIdx].second == TargetLowering::C_Other ||
152 G[BestIdx].second == TargetLowering::C_Immediate);
153 ++BestIdx)
154 ;
155 OpInfo.ConstraintCode = G[BestIdx].first;
156 OpInfo.ConstraintType = G[BestIdx].second;
157 }
158
159 // 'X' matches anything.
160 if (OpInfo.ConstraintCode == "X" && OpInfo.CallOperandVal) {
161 // Labels and constants are handled elsewhere ('X' is the only thing
162 // that matches labels). For Functions, the type here is the type of
163 // the result, which is not what we want to look at; leave them alone.
164 Value *Val = OpInfo.CallOperandVal;
165 if (isa<BasicBlock>(Val) || isa<ConstantInt>(Val) || isa<Function>(Val))
166 return;
167
168 // Otherwise, try to resolve it to something we know about by looking at
169 // the actual operand type.
170 if (const char *Repl = TLI->LowerXConstraint(OpInfo.ConstraintVT)) {
171 OpInfo.ConstraintCode = Repl;
172 OpInfo.ConstraintType = TLI->getConstraintType(OpInfo.ConstraintCode);
173 }
174 }
175}
176
177static unsigned getNumOpRegs(const MachineInstr &I, unsigned OpIdx) {
178 const InlineAsm::Flag F(I.getOperand(OpIdx).getImm());
179 return F.getNumOperandRegisters();
180}
181
183 MachineIRBuilder &MIRBuilder) {
184 const TargetRegisterInfo *TRI =
185 MIRBuilder.getMF().getSubtarget().getRegisterInfo();
186 MachineRegisterInfo *MRI = MIRBuilder.getMRI();
187
188 auto SrcTy = MRI->getType(Src);
189 if (!SrcTy.isValid()) {
190 LLVM_DEBUG(dbgs() << "Source type for copy is not valid\n");
191 return false;
192 }
193 unsigned SrcSize = TRI->getRegSizeInBits(Src, *MRI);
194 unsigned DstSize = TRI->getRegSizeInBits(Dst, *MRI);
195
196 if (DstSize < SrcSize) {
197 LLVM_DEBUG(dbgs() << "Input can't fit in destination reg class\n");
198 return false;
199 }
200
201 // Attempt to anyext small scalar sources.
202 if (DstSize > SrcSize) {
203 if (!SrcTy.isScalar()) {
204 LLVM_DEBUG(dbgs() << "Can't extend non-scalar input to size of"
205 "destination register class\n");
206 return false;
207 }
208 Src = MIRBuilder.buildAnyExt(LLT::scalar(DstSize), Src).getReg(0);
209 }
210
211 MIRBuilder.buildCopy(Dst, Src);
212 return true;
213}
214
216 MachineIRBuilder &MIRBuilder, const CallBase &Call,
217 std::function<ArrayRef<Register>(const Value &Val)> GetOrCreateVRegs)
218 const {
219 const InlineAsm *IA = cast<InlineAsm>(Call.getCalledOperand());
220
221 /// ConstraintOperands - Information about all of the constraints.
222 GISelAsmOperandInfoVector ConstraintOperands;
223
224 MachineFunction &MF = MIRBuilder.getMF();
225 const Function &F = MF.getFunction();
226 const DataLayout &DL = F.getDataLayout();
228
229 MachineRegisterInfo *MRI = MIRBuilder.getMRI();
230
231 TargetLowering::AsmOperandInfoVector TargetConstraints =
232 TLI->ParseConstraints(DL, TRI, Call);
233
234 ExtraFlags ExtraInfo(Call);
235 unsigned ArgNo = 0; // ArgNo - The argument of the CallInst.
236 unsigned ResNo = 0; // ResNo - The result number of the next output.
237 for (auto &T : TargetConstraints) {
238 ConstraintOperands.push_back(GISelAsmOperandInfo(T));
239 GISelAsmOperandInfo &OpInfo = ConstraintOperands.back();
240
241 // Compute the value type for each operand.
242 if (OpInfo.hasArg()) {
243 OpInfo.CallOperandVal = Call.getArgOperand(ArgNo);
244
245 if (isa<BasicBlock>(OpInfo.CallOperandVal)) {
246 LLVM_DEBUG(dbgs() << "Basic block input operands not supported yet\n");
247 return false;
248 }
249
250 Type *OpTy = OpInfo.CallOperandVal->getType();
251
252 // If this is an indirect operand, the operand is a pointer to the
253 // accessed type.
254 if (OpInfo.isIndirect) {
255 OpTy = Call.getParamElementType(ArgNo);
256 assert(OpTy && "Indirect operand must have elementtype attribute");
257 }
258
259 // FIXME: Support aggregate input operands
260 if (!OpTy->isSingleValueType()) {
262 dbgs() << "Aggregate input operands are not supported yet\n");
263 return false;
264 }
265
266 OpInfo.ConstraintVT =
267 TLI->getAsmOperandValueType(DL, OpTy, true).getSimpleVT();
268 ++ArgNo;
269 } else if (OpInfo.Type == InlineAsm::isOutput && !OpInfo.isIndirect) {
270 assert(!Call.getType()->isVoidTy() && "Bad inline asm!");
271 if (StructType *STy = dyn_cast<StructType>(Call.getType())) {
272 OpInfo.ConstraintVT =
273 TLI->getSimpleValueType(DL, STy->getElementType(ResNo));
274 } else {
275 assert(ResNo == 0 && "Asm only has one result!");
276 OpInfo.ConstraintVT =
277 TLI->getAsmOperandValueType(DL, Call.getType()).getSimpleVT();
278 }
279 ++ResNo;
280 } else {
281 assert(OpInfo.Type != InlineAsm::isLabel &&
282 "GlobalISel currently doesn't support callbr");
283 OpInfo.ConstraintVT = MVT::Other;
284 }
285
286 if (OpInfo.ConstraintVT == MVT::i64x8)
287 return false;
288
289 // Compute the constraint code and ConstraintType to use.
290 computeConstraintToUse(TLI, OpInfo);
291
292 // The selected constraint type might expose new sideeffects
293 ExtraInfo.update(OpInfo);
294 }
295
296 // At this point, all operand types are decided.
297 // Create the MachineInstr, but don't insert it yet since input
298 // operands still need to insert instructions before this one
299 auto Inst = MIRBuilder.buildInstrNoInsert(TargetOpcode::INLINEASM)
300 .addExternalSymbol(IA->getAsmString().data())
301 .addImm(ExtraInfo.get());
302
303 // Starting from this operand: flag followed by register(s) will be added as
304 // operands to Inst for each constraint. Used for matching input constraints.
305 unsigned StartIdx = Inst->getNumOperands();
306
307 // Collects the output operands for later processing
308 GISelAsmOperandInfoVector OutputOperands;
309
310 for (auto &OpInfo : ConstraintOperands) {
311 GISelAsmOperandInfo &RefOpInfo =
313 ? ConstraintOperands[OpInfo.getMatchedOperand()]
314 : OpInfo;
315
316 // Assign registers for register operands
317 getRegistersForValue(MF, MIRBuilder, OpInfo, RefOpInfo);
318
319 switch (OpInfo.Type) {
322 const InlineAsm::ConstraintCode ConstraintID =
325 "Failed to convert memory constraint code to constraint id.");
326
327 // Add information to the INLINEASM instruction to know about this
328 // output.
330 Flag.setMemConstraint(ConstraintID);
331 Inst.addImm(Flag);
332 ArrayRef<Register> SourceRegs =
333 GetOrCreateVRegs(*OpInfo.CallOperandVal);
334 assert(
335 SourceRegs.size() == 1 &&
336 "Expected the memory output to fit into a single virtual register");
337 Inst.addReg(SourceRegs[0]);
338 } else {
339 // Otherwise, this outputs to a register (directly for C_Register /
340 // C_RegisterClass/C_Other.
344
345 // Find a register that we can use.
346 if (OpInfo.Regs.empty()) {
348 << "Couldn't allocate output register for constraint\n");
349 return false;
350 }
351
352 // Add information to the INLINEASM instruction to know that this
353 // register is set.
357 OpInfo.Regs.size());
358 if (OpInfo.Regs.front().isVirtual()) {
359 // Put the register class of the virtual registers in the flag word.
360 // That way, later passes can recompute register class constraints for
361 // inline assembly as well as normal instructions. Don't do this for
362 // tied operands that can use the regclass information from the def.
363 const TargetRegisterClass *RC = MRI->getRegClass(OpInfo.Regs.front());
364 Flag.setRegClass(RC->getID());
365 }
366
367 Inst.addImm(Flag);
368
369 for (Register Reg : OpInfo.Regs) {
370 Inst.addReg(Reg,
371 RegState::Define | getImplRegState(Reg.isPhysical()) |
373 }
374
375 // Remember this output operand for later processing
376 OutputOperands.push_back(OpInfo);
377 }
378
379 break;
381 case InlineAsm::isLabel: {
382 if (OpInfo.isMatchingInputConstraint()) {
383 unsigned DefIdx = OpInfo.getMatchedOperand();
384 // Find operand with register def that corresponds to DefIdx.
385 unsigned InstFlagIdx = StartIdx;
386 for (unsigned i = 0; i < DefIdx; ++i)
387 InstFlagIdx += getNumOpRegs(*Inst, InstFlagIdx) + 1;
388 assert(getNumOpRegs(*Inst, InstFlagIdx) == 1 && "Wrong flag");
389
390 const InlineAsm::Flag MatchedOperandFlag(Inst->getOperand(InstFlagIdx).getImm());
391 if (MatchedOperandFlag.isMemKind()) {
392 LLVM_DEBUG(dbgs() << "Matching input constraint to mem operand not "
393 "supported. This should be target specific.\n");
394 return false;
395 }
396 if (!MatchedOperandFlag.isRegDefKind() && !MatchedOperandFlag.isRegDefEarlyClobberKind()) {
397 LLVM_DEBUG(dbgs() << "Unknown matching constraint\n");
398 return false;
399 }
400
401 // We want to tie input to register in next operand.
402 unsigned DefRegIdx = InstFlagIdx + 1;
403 Register Def = Inst->getOperand(DefRegIdx).getReg();
404
405 ArrayRef<Register> SrcRegs = GetOrCreateVRegs(*OpInfo.CallOperandVal);
406 assert(SrcRegs.size() == 1 && "Single register is expected here");
407
408 // When Def is physreg: use given input.
409 Register In = SrcRegs[0];
410 // When Def is vreg: copy input to new vreg with same reg class as Def.
411 if (Def.isVirtual()) {
412 In = MRI->createVirtualRegister(MRI->getRegClass(Def));
413 if (!buildAnyextOrCopy(In, SrcRegs[0], MIRBuilder))
414 return false;
415 }
416
417 // Add Flag and input register operand (In) to Inst. Tie In to Def.
419 UseFlag.setMatchingOp(DefIdx);
420 Inst.addImm(UseFlag);
421 Inst.addReg(In);
422 Inst->tieOperands(DefRegIdx, Inst->getNumOperands() - 1);
423 break;
424 }
425
427 OpInfo.isIndirect) {
428 LLVM_DEBUG(dbgs() << "Indirect input operands with unknown constraint "
429 "not supported yet\n");
430 return false;
431 }
432
435
436 std::vector<MachineOperand> Ops;
438 OpInfo.ConstraintCode, Ops,
439 MIRBuilder)) {
440 LLVM_DEBUG(dbgs() << "Don't support constraint: "
441 << OpInfo.ConstraintCode << " yet\n");
442 return false;
443 }
444
445 assert(Ops.size() > 0 &&
446 "Expected constraint to be lowered to at least one operand");
447
448 // Add information to the INLINEASM node to know about this input.
449 const unsigned OpFlags =
451 Inst.addImm(OpFlags);
452 Inst.add(Ops);
453 break;
454 }
455
457
458 if (!OpInfo.isIndirect) {
460 << "Cannot indirectify memory input operands yet\n");
461 return false;
462 }
463
464 assert(OpInfo.isIndirect && "Operand must be indirect to be a mem!");
465
466 const InlineAsm::ConstraintCode ConstraintID =
469 OpFlags.setMemConstraint(ConstraintID);
470 Inst.addImm(OpFlags);
471 ArrayRef<Register> SourceRegs =
472 GetOrCreateVRegs(*OpInfo.CallOperandVal);
473 assert(
474 SourceRegs.size() == 1 &&
475 "Expected the memory input to fit into a single virtual register");
476 Inst.addReg(SourceRegs[0]);
477 break;
478 }
479
482 "Unknown constraint type!");
483
484 if (OpInfo.isIndirect) {
485 LLVM_DEBUG(dbgs() << "Can't handle indirect register inputs yet "
486 "for constraint '"
487 << OpInfo.ConstraintCode << "'\n");
488 return false;
489 }
490
491 // Copy the input into the appropriate registers.
492 if (OpInfo.Regs.empty()) {
494 dbgs()
495 << "Couldn't allocate input register for register constraint\n");
496 return false;
497 }
498
499 unsigned NumRegs = OpInfo.Regs.size();
500 ArrayRef<Register> SourceRegs = GetOrCreateVRegs(*OpInfo.CallOperandVal);
501 assert(NumRegs == SourceRegs.size() &&
502 "Expected the number of input registers to match the number of "
503 "source registers");
504
505 if (NumRegs > 1) {
506 LLVM_DEBUG(dbgs() << "Input operands with multiple input registers are "
507 "not supported yet\n");
508 return false;
509 }
510
512 if (OpInfo.Regs.front().isVirtual()) {
513 // Put the register class of the virtual registers in the flag word.
514 const TargetRegisterClass *RC = MRI->getRegClass(OpInfo.Regs.front());
515 Flag.setRegClass(RC->getID());
516 }
517 Inst.addImm(Flag);
518 if (!buildAnyextOrCopy(OpInfo.Regs[0], SourceRegs[0], MIRBuilder))
519 return false;
520 Inst.addReg(OpInfo.Regs[0]);
521 break;
522 }
523
525
526 const unsigned NumRegs = OpInfo.Regs.size();
527 if (NumRegs > 0) {
528 unsigned Flag = InlineAsm::Flag(InlineAsm::Kind::Clobber, NumRegs);
529 Inst.addImm(Flag);
530
531 for (Register Reg : OpInfo.Regs) {
532 Inst.addReg(Reg, RegState::Define | RegState::EarlyClobber |
533 getImplRegState(Reg.isPhysical()));
534 }
535 }
536 break;
537 }
538 }
539 }
540
541 // Add rounding control registers as implicit def for inline asm.
542 if (MF.getFunction().hasFnAttribute(Attribute::StrictFP)) {
544 for (MCPhysReg Reg : RCRegs)
545 Inst.addReg(Reg, RegState::ImplicitDefine);
546 }
547
548 if (auto Bundle = Call.getOperandBundle(LLVMContext::OB_convergencectrl)) {
549 auto *Token = Bundle->Inputs[0].get();
550 ArrayRef<Register> SourceRegs = GetOrCreateVRegs(*Token);
551 assert(SourceRegs.size() == 1 &&
552 "Expected the control token to fit into a single virtual register");
553 Inst.addUse(SourceRegs[0], RegState::Implicit);
554 }
555
556 if (const MDNode *SrcLoc = Call.getMetadata("srcloc"))
557 Inst.addMetadata(SrcLoc);
558
559 // All inputs are handled, insert the instruction now
560 MIRBuilder.insertInstr(Inst);
561
562 // Finally, copy the output operands into the output registers
563 ArrayRef<Register> ResRegs = GetOrCreateVRegs(Call);
564 if (ResRegs.size() != OutputOperands.size()) {
565 LLVM_DEBUG(dbgs() << "Expected the number of output registers to match the "
566 "number of destination registers\n");
567 return false;
568 }
569 for (unsigned int i = 0, e = ResRegs.size(); i < e; i++) {
570 GISelAsmOperandInfo &OpInfo = OutputOperands[i];
571
572 if (OpInfo.Regs.empty())
573 continue;
574
575 switch (OpInfo.ConstraintType) {
578 if (OpInfo.Regs.size() > 1) {
579 LLVM_DEBUG(dbgs() << "Output operands with multiple defining "
580 "registers are not supported yet\n");
581 return false;
582 }
583
584 Register SrcReg = OpInfo.Regs[0];
585 unsigned SrcSize = TRI->getRegSizeInBits(SrcReg, *MRI);
586 LLT ResTy = MRI->getType(ResRegs[i]);
587 if (ResTy.isScalar() && ResTy.getSizeInBits() < SrcSize) {
588 // First copy the non-typed virtual register into a generic virtual
589 // register
590 Register Tmp1Reg =
591 MRI->createGenericVirtualRegister(LLT::scalar(SrcSize));
592 MIRBuilder.buildCopy(Tmp1Reg, SrcReg);
593 // Need to truncate the result of the register
594 MIRBuilder.buildTrunc(ResRegs[i], Tmp1Reg);
595 } else if (ResTy.getSizeInBits() == SrcSize) {
596 MIRBuilder.buildCopy(ResRegs[i], SrcReg);
597 } else {
598 LLVM_DEBUG(dbgs() << "Unhandled output operand with "
599 "mismatched register size\n");
600 return false;
601 }
602
603 break;
604 }
608 dbgs() << "Cannot lower target specific output constraints yet\n");
609 return false;
611 break; // Already handled.
613 break; // Silence warning.
615 LLVM_DEBUG(dbgs() << "Unexpected unknown constraint\n");
616 return false;
617 }
618 }
619
620 return true;
621}
622
624 Value *Val, StringRef Constraint, std::vector<MachineOperand> &Ops,
625 MachineIRBuilder &MIRBuilder) const {
626 if (Constraint.size() > 1)
627 return false;
628
629 char ConstraintLetter = Constraint[0];
630 switch (ConstraintLetter) {
631 default:
632 return false;
633 case 'i': // Simple Integer or Relocatable Constant
634 case 'n': // immediate integer with a known value.
635 if (ConstantInt *CI = dyn_cast<ConstantInt>(Val)) {
636 assert(CI->getBitWidth() <= 64 &&
637 "expected immediate to fit into 64-bits");
638 // Boolean constants should be zero-extended, others are sign-extended
639 bool IsBool = CI->getBitWidth() == 1;
640 int64_t ExtVal = IsBool ? CI->getZExtValue() : CI->getSExtValue();
641 Ops.push_back(MachineOperand::CreateImm(ExtVal));
642 return true;
643 }
644 return false;
645 }
646}
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
Module.h This file contains the declarations for the Module class.
static unsigned getNumOpRegs(const MachineInstr &I, unsigned OpIdx)
static void getRegistersForValue(MachineFunction &MF, MachineIRBuilder &MIRBuilder, GISelAsmOperandInfo &OpInfo, GISelAsmOperandInfo &RefOpInfo)
Assign virtual/physical registers for the specified register operand.
static void computeConstraintToUse(const TargetLowering *TLI, TargetLowering::AsmOperandInfo &OpInfo)
static bool buildAnyextOrCopy(Register Dst, Register Src, MachineIRBuilder &MIRBuilder)
This file describes how to lower LLVM inline asm to machine code INLINEASM.
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
#define G(x, y, z)
Definition: MD5.cpp:56
This file declares the MachineIRBuilder class.
Register const TargetRegisterInfo * TRI
MachineInstr unsigned OpIdx
#define LLVM_DEBUG(...)
Definition: Debug.h:119
This file describes how to lower LLVM code to machine code.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:147
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Definition: InstrTypes.h:1116
Value * getCalledOperand() const
Definition: InstrTypes.h:1340
bool isConvergent() const
Determine if the invoke is convergent.
Definition: InstrTypes.h:1967
This is the shared class of boolean and integer constants.
Definition: Constants.h:87
A parsed version of the target data layout string in and methods for querying it.
Definition: DataLayout.h:63
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Definition: Function.cpp:359
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition: Function.cpp:727
bool lowerInlineAsm(MachineIRBuilder &MIRBuilder, const CallBase &CB, std::function< ArrayRef< Register >(const Value &Val)> GetOrCreateVRegs) const
Lower the given inline asm call instruction GetOrCreateVRegs is a callback to materialize a register ...
virtual bool lowerAsmOperandForConstraint(Value *Val, StringRef Constraint, std::vector< MachineOperand > &Ops, MachineIRBuilder &MIRBuilder) const
Lower the specified operand into the Ops vector.
bool isMemKind() const
Definition: InlineAsm.h:337
void setMatchingOp(unsigned OperandNo)
setMatchingOp - Augment an existing flag with information indicating that this input operand is tied ...
Definition: InlineAsm.h:394
void setMemConstraint(ConstraintCode C)
setMemConstraint - Augment an existing flag with the constraint code for a memory constraint.
Definition: InlineAsm.h:413
bool isRegDefEarlyClobberKind() const
Definition: InlineAsm.h:332
bool isRegDefKind() const
Definition: InlineAsm.h:331
constexpr bool isScalar() const
Definition: LowLevelType.h:147
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
Definition: LowLevelType.h:43
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
Definition: LowLevelType.h:191
Metadata node.
Definition: Metadata.h:1077
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Helper class to build MachineInstr.
MachineInstrBuilder insertInstr(MachineInstrBuilder MIB)
Insert an existing instruction at the insertion point.
MachineFunction & getMF()
Getter for the function we currently build.
MachineInstrBuilder buildTrunc(const DstOp &Res, const SrcOp &Op, std::optional< unsigned > Flags=std::nullopt)
Build and insert Res = G_TRUNC Op.
MachineInstrBuilder buildAnyExt(const DstOp &Res, const SrcOp &Op)
Build and insert Res = G_ANYEXT Op0.
MachineRegisterInfo * getMRI()
Getter for MRI.
MachineInstrBuilder buildInstrNoInsert(unsigned Opcode)
Build but don't insert <empty> = Opcode <empty>.
MachineInstrBuilder buildCopy(const DstOp &Res, const SrcOp &Op)
Build and insert Res = COPY Op.
Register getReg(unsigned Idx) const
Get the register for the operand index.
const MachineInstrBuilder & addExternalSymbol(const char *FnName, unsigned TargetFlags=0) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
Representation of each machine instruction.
Definition: MachineInstr.h:72
unsigned getNumOperands() const
Retuns the total number of operands.
Definition: MachineInstr.h:590
static MachineOperand CreateImm(int64_t Val)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:55
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:154
Class to represent struct types.
Definition: DerivedTypes.h:218
virtual unsigned getNumRegisters(LLVMContext &Context, EVT VT, std::optional< MVT > RegisterVT=std::nullopt) const
Return the number of registers that this ValueType will eventually require.
MVT getSimpleValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the MVT corresponding to this LLVM type. See getValueType.
virtual EVT getAsmOperandValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
virtual InlineAsm::ConstraintCode getInlineAsmMemConstraint(StringRef ConstraintCode) const
std::vector< AsmOperandInfo > AsmOperandInfoVector
virtual ConstraintType getConstraintType(StringRef Constraint) const
Given a constraint, return the type of constraint it is for this target.
virtual const char * LowerXConstraint(EVT ConstraintVT) const
Try to replace an X constraint, which matches anything, with another that has more specific requireme...
ConstraintGroup getConstraintPreferences(AsmOperandInfo &OpInfo) const
Given an OpInfo with list of constraints codes as strings, return a sorted Vector of pairs of constra...
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
virtual AsmOperandInfoVector ParseConstraints(const DataLayout &DL, const TargetRegisterInfo *TRI, const CallBase &Call) const
Split up the constraint string from the inline assembly value into the specific constraints and their...
virtual ArrayRef< MCPhysReg > getRoundingControlRegisters() const
Returns a 0 terminated array of rounding control registers that can be attached into strict FP call.
unsigned getID() const
Return the register class ID number.
iterator begin() const
begin/end - Return all of the registers in this class.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
virtual const TargetLowering * getTargetLowering() const
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
bool isSingleValueType() const
Return true if the type is a valid type for a register in codegen.
Definition: Type.h:296
LLVM Value Representation.
Definition: Value.h:75
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Define
Register definition.
@ EarlyClobber
Register definition happens before uses.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
unsigned getImplRegState(bool B)
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:207
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition: ValueTypes.h:311
ConstraintPrefix Type
Type - The basic type of the constraint: input/output/clobber/label.
Definition: InlineAsm.h:128
ConstraintCodeVector Codes
Code - The constraint code, either the register name (in braces) or the constraint letter/number.
Definition: InlineAsm.h:156
bool isIndirect
isIndirect - True if this operand is an indirect operand.
Definition: InlineAsm.h:152
bool isEarlyClobber
isEarlyClobber - "&": output operand writes result before inputs are all read.
Definition: InlineAsm.h:132
This contains information for each constraint that we are lowering.
MVT ConstraintVT
The ValueType for the operand value.
TargetLowering::ConstraintType ConstraintType
Information about the constraint code, e.g.
std::string ConstraintCode
This contains the actual string for the code, like "m".
Value * CallOperandVal
If this is the result output operand or a clobber, this is null, otherwise it is the incoming operand...
LLVM_ABI unsigned getMatchedOperand() const
If this is an input matching constraint, this method returns the output operand it matches.
LLVM_ABI bool isMatchingInputConstraint() const
Return true of this is an input operand that is a matching constraint like "4".