LLVM  14.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 
15 #include "llvm/CodeGen/Analysis.h"
21 #include "llvm/IR/DataLayout.h"
22 #include "llvm/IR/Instructions.h"
23 #include "llvm/IR/LLVMContext.h"
24 #include "llvm/IR/Module.h"
25 
26 #define DEBUG_TYPE "inline-asm-lowering"
27 
28 using namespace llvm;
29 
30 void InlineAsmLowering::anchor() {}
31 
32 namespace {
33 
34 /// GISelAsmOperandInfo - This contains information for each constraint that we
35 /// are lowering.
36 class GISelAsmOperandInfo : public TargetLowering::AsmOperandInfo {
37 public:
38  /// Regs - If this is a register or register class operand, this
39  /// contains the set of assigned registers corresponding to the operand.
41 
42  explicit GISelAsmOperandInfo(const TargetLowering::AsmOperandInfo &Info)
43  : TargetLowering::AsmOperandInfo(Info) {}
44 };
45 
46 using GISelAsmOperandInfoVector = SmallVector<GISelAsmOperandInfo, 16>;
47 
48 class ExtraFlags {
49  unsigned Flags = 0;
50 
51 public:
52  explicit ExtraFlags(const CallBase &CB) {
53  const InlineAsm *IA = cast<InlineAsm>(CB.getCalledOperand());
54  if (IA->hasSideEffects())
56  if (IA->isAlignStack())
58  if (CB.isConvergent())
60  Flags |= IA->getDialect() * InlineAsm::Extra_AsmDialect;
61  }
62 
63  void update(const TargetLowering::AsmOperandInfo &OpInfo) {
64  // Ideally, we would only check against memory constraints. However, the
65  // meaning of an Other constraint can be target-specific and we can't easily
66  // reason about it. Therefore, be conservative and set MayLoad/MayStore
67  // for Other constraints as well.
70  if (OpInfo.Type == InlineAsm::isInput)
71  Flags |= InlineAsm::Extra_MayLoad;
72  else if (OpInfo.Type == InlineAsm::isOutput)
74  else if (OpInfo.Type == InlineAsm::isClobber)
76  }
77  }
78 
79  unsigned get() const { return Flags; }
80 };
81 
82 } // namespace
83 
84 /// Assign virtual/physical registers for the specified register operand.
86  MachineIRBuilder &MIRBuilder,
87  GISelAsmOperandInfo &OpInfo,
88  GISelAsmOperandInfo &RefOpInfo) {
89 
90  const TargetLowering &TLI = *MF.getSubtarget().getTargetLowering();
92 
93  // No work to do for memory operations.
94  if (OpInfo.ConstraintType == TargetLowering::C_Memory)
95  return;
96 
97  // If this is a constraint for a single physreg, or a constraint for a
98  // register class, find it.
99  Register AssignedReg;
100  const TargetRegisterClass *RC;
101  std::tie(AssignedReg, RC) = TLI.getRegForInlineAsmConstraint(
102  &TRI, RefOpInfo.ConstraintCode, RefOpInfo.ConstraintVT);
103  // RC is unset only on failure. Return immediately.
104  if (!RC)
105  return;
106 
107  // No need to allocate a matching input constraint since the constraint it's
108  // matching to has already been allocated.
109  if (OpInfo.isMatchingInputConstraint())
110  return;
111 
112  // Initialize NumRegs.
113  unsigned NumRegs = 1;
114  if (OpInfo.ConstraintVT != MVT::Other)
115  NumRegs =
116  TLI.getNumRegisters(MF.getFunction().getContext(), OpInfo.ConstraintVT);
117 
118  // If this is a constraint for a specific physical register, but the type of
119  // the operand requires more than one register to be passed, we allocate the
120  // required amount of physical registers, starting from the selected physical
121  // register.
122  // For this, first retrieve a register iterator for the given register class
124  MachineRegisterInfo &RegInfo = MF.getRegInfo();
125 
126  // Advance the iterator to the assigned register (if set)
127  if (AssignedReg) {
128  for (; *I != AssignedReg; ++I)
129  assert(I != RC->end() && "AssignedReg should be a member of provided RC");
130  }
131 
132  // Finally, assign the registers. If the AssignedReg isn't set, create virtual
133  // registers with the provided register class
134  for (; NumRegs; --NumRegs, ++I) {
135  assert(I != RC->end() && "Ran out of registers to allocate!");
136  Register R = AssignedReg ? Register(*I) : RegInfo.createVirtualRegister(RC);
137  OpInfo.Regs.push_back(R);
138  }
139 }
140 
141 /// Return an integer indicating how general CT is.
143  switch (CT) {
147  return 0;
149  return 1;
151  return 2;
153  return 3;
154  }
155  llvm_unreachable("Invalid constraint type");
156 }
157 
159  const TargetLowering *TLI) {
160  assert(OpInfo.Codes.size() > 1 && "Doesn't have multiple constraint options");
161  unsigned BestIdx = 0;
163  int BestGenerality = -1;
164 
165  // Loop over the options, keeping track of the most general one.
166  for (unsigned i = 0, e = OpInfo.Codes.size(); i != e; ++i) {
168  TLI->getConstraintType(OpInfo.Codes[i]);
169 
170  // Indirect 'other' or 'immediate' constraints are not allowed.
171  if (OpInfo.isIndirect && !(CType == TargetLowering::C_Memory ||
172  CType == TargetLowering::C_Register ||
174  continue;
175 
176  // If this is an 'other' or 'immediate' constraint, see if the operand is
177  // valid for it. For example, on X86 we might have an 'rI' constraint. If
178  // the operand is an integer in the range [0..31] we want to use I (saving a
179  // load of a register), otherwise we must use 'r'.
180  if (CType == TargetLowering::C_Other ||
181  CType == TargetLowering::C_Immediate) {
182  assert(OpInfo.Codes[i].size() == 1 &&
183  "Unhandled multi-letter 'other' constraint");
184  // FIXME: prefer immediate constraints if the target allows it
185  }
186 
187  // Things with matching constraints can only be registers, per gcc
188  // documentation. This mainly affects "g" constraints.
189  if (CType == TargetLowering::C_Memory && OpInfo.hasMatchingInput())
190  continue;
191 
192  // This constraint letter is more general than the previous one, use it.
193  int Generality = getConstraintGenerality(CType);
194  if (Generality > BestGenerality) {
195  BestType = CType;
196  BestIdx = i;
197  BestGenerality = Generality;
198  }
199  }
200 
201  OpInfo.ConstraintCode = OpInfo.Codes[BestIdx];
202  OpInfo.ConstraintType = BestType;
203 }
204 
205 static void computeConstraintToUse(const TargetLowering *TLI,
207  assert(!OpInfo.Codes.empty() && "Must have at least one constraint");
208 
209  // Single-letter constraints ('r') are very common.
210  if (OpInfo.Codes.size() == 1) {
211  OpInfo.ConstraintCode = OpInfo.Codes[0];
212  OpInfo.ConstraintType = TLI->getConstraintType(OpInfo.ConstraintCode);
213  } else {
214  chooseConstraint(OpInfo, TLI);
215  }
216 
217  // 'X' matches anything.
218  if (OpInfo.ConstraintCode == "X" && OpInfo.CallOperandVal) {
219  // Labels and constants are handled elsewhere ('X' is the only thing
220  // that matches labels). For Functions, the type here is the type of
221  // the result, which is not what we want to look at; leave them alone.
222  Value *Val = OpInfo.CallOperandVal;
223  if (isa<BasicBlock>(Val) || isa<ConstantInt>(Val) || isa<Function>(Val))
224  return;
225 
226  // Otherwise, try to resolve it to something we know about by looking at
227  // the actual operand type.
228  if (const char *Repl = TLI->LowerXConstraint(OpInfo.ConstraintVT)) {
229  OpInfo.ConstraintCode = Repl;
230  OpInfo.ConstraintType = TLI->getConstraintType(OpInfo.ConstraintCode);
231  }
232  }
233 }
234 
235 static unsigned getNumOpRegs(const MachineInstr &I, unsigned OpIdx) {
236  unsigned Flag = I.getOperand(OpIdx).getImm();
238 }
239 
240 static bool buildAnyextOrCopy(Register Dst, Register Src,
241  MachineIRBuilder &MIRBuilder) {
242  const TargetRegisterInfo *TRI =
243  MIRBuilder.getMF().getSubtarget().getRegisterInfo();
244  MachineRegisterInfo *MRI = MIRBuilder.getMRI();
245 
246  auto SrcTy = MRI->getType(Src);
247  if (!SrcTy.isValid()) {
248  LLVM_DEBUG(dbgs() << "Source type for copy is not valid\n");
249  return false;
250  }
251  unsigned SrcSize = TRI->getRegSizeInBits(Src, *MRI);
252  unsigned DstSize = TRI->getRegSizeInBits(Dst, *MRI);
253 
254  if (DstSize < SrcSize) {
255  LLVM_DEBUG(dbgs() << "Input can't fit in destination reg class\n");
256  return false;
257  }
258 
259  // Attempt to anyext small scalar sources.
260  if (DstSize > SrcSize) {
261  if (!SrcTy.isScalar()) {
262  LLVM_DEBUG(dbgs() << "Can't extend non-scalar input to size of"
263  "destination register class\n");
264  return false;
265  }
266  Src = MIRBuilder.buildAnyExt(LLT::scalar(DstSize), Src).getReg(0);
267  }
268 
269  MIRBuilder.buildCopy(Dst, Src);
270  return true;
271 }
272 
274  MachineIRBuilder &MIRBuilder, const CallBase &Call,
275  std::function<ArrayRef<Register>(const Value &Val)> GetOrCreateVRegs)
276  const {
277  const InlineAsm *IA = cast<InlineAsm>(Call.getCalledOperand());
278 
279  /// ConstraintOperands - Information about all of the constraints.
280  GISelAsmOperandInfoVector ConstraintOperands;
281 
282  MachineFunction &MF = MIRBuilder.getMF();
283  const Function &F = MF.getFunction();
284  const DataLayout &DL = F.getParent()->getDataLayout();
286 
287  MachineRegisterInfo *MRI = MIRBuilder.getMRI();
288 
289  TargetLowering::AsmOperandInfoVector TargetConstraints =
290  TLI->ParseConstraints(DL, TRI, Call);
291 
292  ExtraFlags ExtraInfo(Call);
293  unsigned ArgNo = 0; // ArgNo - The argument of the CallInst.
294  unsigned ResNo = 0; // ResNo - The result number of the next output.
295  for (auto &T : TargetConstraints) {
296  ConstraintOperands.push_back(GISelAsmOperandInfo(T));
297  GISelAsmOperandInfo &OpInfo = ConstraintOperands.back();
298 
299  // Compute the value type for each operand.
300  if (OpInfo.Type == InlineAsm::isInput ||
301  (OpInfo.Type == InlineAsm::isOutput && OpInfo.isIndirect)) {
302 
303  OpInfo.CallOperandVal = const_cast<Value *>(Call.getArgOperand(ArgNo++));
304 
305  if (isa<BasicBlock>(OpInfo.CallOperandVal)) {
306  LLVM_DEBUG(dbgs() << "Basic block input operands not supported yet\n");
307  return false;
308  }
309 
310  Type *OpTy = OpInfo.CallOperandVal->getType();
311 
312  // If this is an indirect operand, the operand is a pointer to the
313  // accessed type.
314  if (OpInfo.isIndirect) {
315  PointerType *PtrTy = dyn_cast<PointerType>(OpTy);
316  if (!PtrTy)
317  report_fatal_error("Indirect operand for inline asm not a pointer!");
318  OpTy = PtrTy->getElementType();
319  }
320 
321  // FIXME: Support aggregate input operands
322  if (!OpTy->isSingleValueType()) {
323  LLVM_DEBUG(
324  dbgs() << "Aggregate input operands are not supported yet\n");
325  return false;
326  }
327 
328  OpInfo.ConstraintVT =
329  TLI->getAsmOperandValueType(DL, OpTy, true).getSimpleVT();
330 
331  } else if (OpInfo.Type == InlineAsm::isOutput && !OpInfo.isIndirect) {
332  assert(!Call.getType()->isVoidTy() && "Bad inline asm!");
333  if (StructType *STy = dyn_cast<StructType>(Call.getType())) {
334  OpInfo.ConstraintVT =
335  TLI->getSimpleValueType(DL, STy->getElementType(ResNo));
336  } else {
337  assert(ResNo == 0 && "Asm only has one result!");
338  OpInfo.ConstraintVT =
339  TLI->getAsmOperandValueType(DL, Call.getType()).getSimpleVT();
340  }
341  ++ResNo;
342  } else {
343  OpInfo.ConstraintVT = MVT::Other;
344  }
345 
346  if (OpInfo.ConstraintVT == MVT::i64x8)
347  return false;
348 
349  // Compute the constraint code and ConstraintType to use.
350  computeConstraintToUse(TLI, OpInfo);
351 
352  // The selected constraint type might expose new sideeffects
353  ExtraInfo.update(OpInfo);
354  }
355 
356  // At this point, all operand types are decided.
357  // Create the MachineInstr, but don't insert it yet since input
358  // operands still need to insert instructions before this one
359  auto Inst = MIRBuilder.buildInstrNoInsert(TargetOpcode::INLINEASM)
360  .addExternalSymbol(IA->getAsmString().c_str())
361  .addImm(ExtraInfo.get());
362 
363  // Starting from this operand: flag followed by register(s) will be added as
364  // operands to Inst for each constraint. Used for matching input constraints.
365  unsigned StartIdx = Inst->getNumOperands();
366 
367  // Collects the output operands for later processing
368  GISelAsmOperandInfoVector OutputOperands;
369 
370  for (auto &OpInfo : ConstraintOperands) {
371  GISelAsmOperandInfo &RefOpInfo =
373  ? ConstraintOperands[OpInfo.getMatchedOperand()]
374  : OpInfo;
375 
376  // Assign registers for register operands
377  getRegistersForValue(MF, MIRBuilder, OpInfo, RefOpInfo);
378 
379  switch (OpInfo.Type) {
380  case InlineAsm::isOutput:
382  unsigned ConstraintID =
384  assert(ConstraintID != InlineAsm::Constraint_Unknown &&
385  "Failed to convert memory constraint code to constraint id.");
386 
387  // Add information to the INLINEASM instruction to know about this
388  // output.
389  unsigned OpFlags = InlineAsm::getFlagWord(InlineAsm::Kind_Mem, 1);
390  OpFlags = InlineAsm::getFlagWordForMem(OpFlags, ConstraintID);
391  Inst.addImm(OpFlags);
392  ArrayRef<Register> SourceRegs =
393  GetOrCreateVRegs(*OpInfo.CallOperandVal);
394  assert(
395  SourceRegs.size() == 1 &&
396  "Expected the memory output to fit into a single virtual register");
397  Inst.addReg(SourceRegs[0]);
398  } else {
399  // Otherwise, this outputs to a register (directly for C_Register /
400  // C_RegisterClass. Find a register that we can use.
403 
404  if (OpInfo.Regs.empty()) {
405  LLVM_DEBUG(dbgs()
406  << "Couldn't allocate output register for constraint\n");
407  return false;
408  }
409 
410  // Add information to the INLINEASM instruction to know that this
411  // register is set.
412  unsigned Flag = InlineAsm::getFlagWord(
415  OpInfo.Regs.size());
416  if (OpInfo.Regs.front().isVirtual()) {
417  // Put the register class of the virtual registers in the flag word.
418  // That way, later passes can recompute register class constraints for
419  // inline assembly as well as normal instructions. Don't do this for
420  // tied operands that can use the regclass information from the def.
421  const TargetRegisterClass *RC = MRI->getRegClass(OpInfo.Regs.front());
423  }
424 
425  Inst.addImm(Flag);
426 
427  for (Register Reg : OpInfo.Regs) {
428  Inst.addReg(Reg,
429  RegState::Define | getImplRegState(Reg.isPhysical()) |
430  (OpInfo.isEarlyClobber ? RegState::EarlyClobber : 0));
431  }
432 
433  // Remember this output operand for later processing
434  OutputOperands.push_back(OpInfo);
435  }
436 
437  break;
438  case InlineAsm::isInput: {
439  if (OpInfo.isMatchingInputConstraint()) {
440  unsigned DefIdx = OpInfo.getMatchedOperand();
441  // Find operand with register def that corresponds to DefIdx.
442  unsigned InstFlagIdx = StartIdx;
443  for (unsigned i = 0; i < DefIdx; ++i)
444  InstFlagIdx += getNumOpRegs(*Inst, InstFlagIdx) + 1;
445  assert(getNumOpRegs(*Inst, InstFlagIdx) == 1 && "Wrong flag");
446 
447  unsigned MatchedOperandFlag = Inst->getOperand(InstFlagIdx).getImm();
448  if (InlineAsm::isMemKind(MatchedOperandFlag)) {
449  LLVM_DEBUG(dbgs() << "Matching input constraint to mem operand not "
450  "supported. This should be target specific.\n");
451  return false;
452  }
453  if (!InlineAsm::isRegDefKind(MatchedOperandFlag) &&
454  !InlineAsm::isRegDefEarlyClobberKind(MatchedOperandFlag)) {
455  LLVM_DEBUG(dbgs() << "Unknown matching constraint\n");
456  return false;
457  }
458 
459  // We want to tie input to register in next operand.
460  unsigned DefRegIdx = InstFlagIdx + 1;
461  Register Def = Inst->getOperand(DefRegIdx).getReg();
462 
463  ArrayRef<Register> SrcRegs = GetOrCreateVRegs(*OpInfo.CallOperandVal);
464  assert(SrcRegs.size() == 1 && "Single register is expected here");
465 
466  // When Def is physreg: use given input.
467  Register In = SrcRegs[0];
468  // When Def is vreg: copy input to new vreg with same reg class as Def.
469  if (Def.isVirtual()) {
471  if (!buildAnyextOrCopy(In, SrcRegs[0], MIRBuilder))
472  return false;
473  }
474 
475  // Add Flag and input register operand (In) to Inst. Tie In to Def.
476  unsigned UseFlag = InlineAsm::getFlagWord(InlineAsm::Kind_RegUse, 1);
477  unsigned Flag = InlineAsm::getFlagWordForMatchingOp(UseFlag, DefIdx);
478  Inst.addImm(Flag);
479  Inst.addReg(In);
480  Inst->tieOperands(DefRegIdx, Inst->getNumOperands() - 1);
481  break;
482  }
483 
484  if (OpInfo.ConstraintType == TargetLowering::C_Other &&
485  OpInfo.isIndirect) {
486  LLVM_DEBUG(dbgs() << "Indirect input operands with unknown constraint "
487  "not supported yet\n");
488  return false;
489  }
490 
493 
494  std::vector<MachineOperand> Ops;
496  OpInfo.ConstraintCode, Ops,
497  MIRBuilder)) {
498  LLVM_DEBUG(dbgs() << "Don't support constraint: "
499  << OpInfo.ConstraintCode << " yet\n");
500  return false;
501  }
502 
503  assert(Ops.size() > 0 &&
504  "Expected constraint to be lowered to at least one operand");
505 
506  // Add information to the INLINEASM node to know about this input.
507  unsigned OpFlags =
509  Inst.addImm(OpFlags);
510  Inst.add(Ops);
511  break;
512  }
513 
515 
516  if (!OpInfo.isIndirect) {
517  LLVM_DEBUG(dbgs()
518  << "Cannot indirectify memory input operands yet\n");
519  return false;
520  }
521 
522  assert(OpInfo.isIndirect && "Operand must be indirect to be a mem!");
523 
524  unsigned ConstraintID =
526  unsigned OpFlags = InlineAsm::getFlagWord(InlineAsm::Kind_Mem, 1);
527  OpFlags = InlineAsm::getFlagWordForMem(OpFlags, ConstraintID);
528  Inst.addImm(OpFlags);
529  ArrayRef<Register> SourceRegs =
530  GetOrCreateVRegs(*OpInfo.CallOperandVal);
531  assert(
532  SourceRegs.size() == 1 &&
533  "Expected the memory input to fit into a single virtual register");
534  Inst.addReg(SourceRegs[0]);
535  break;
536  }
537 
540  "Unknown constraint type!");
541 
542  if (OpInfo.isIndirect) {
543  LLVM_DEBUG(dbgs() << "Can't handle indirect register inputs yet "
544  "for constraint '"
545  << OpInfo.ConstraintCode << "'\n");
546  return false;
547  }
548 
549  // Copy the input into the appropriate registers.
550  if (OpInfo.Regs.empty()) {
551  LLVM_DEBUG(
552  dbgs()
553  << "Couldn't allocate input register for register constraint\n");
554  return false;
555  }
556 
557  unsigned NumRegs = OpInfo.Regs.size();
558  ArrayRef<Register> SourceRegs = GetOrCreateVRegs(*OpInfo.CallOperandVal);
559  assert(NumRegs == SourceRegs.size() &&
560  "Expected the number of input registers to match the number of "
561  "source registers");
562 
563  if (NumRegs > 1) {
564  LLVM_DEBUG(dbgs() << "Input operands with multiple input registers are "
565  "not supported yet\n");
566  return false;
567  }
568 
570  if (OpInfo.Regs.front().isVirtual()) {
571  // Put the register class of the virtual registers in the flag word.
572  const TargetRegisterClass *RC = MRI->getRegClass(OpInfo.Regs.front());
574  }
575  Inst.addImm(Flag);
576  if (!buildAnyextOrCopy(OpInfo.Regs[0], SourceRegs[0], MIRBuilder))
577  return false;
578  Inst.addReg(OpInfo.Regs[0]);
579  break;
580  }
581 
582  case InlineAsm::isClobber: {
583 
584  unsigned NumRegs = OpInfo.Regs.size();
585  if (NumRegs > 0) {
586  unsigned Flag =
588  Inst.addImm(Flag);
589 
590  for (Register Reg : OpInfo.Regs) {
592  getImplRegState(Reg.isPhysical()));
593  }
594  }
595  break;
596  }
597  }
598  }
599 
600  if (const MDNode *SrcLoc = Call.getMetadata("srcloc"))
601  Inst.addMetadata(SrcLoc);
602 
603  // All inputs are handled, insert the instruction now
604  MIRBuilder.insertInstr(Inst);
605 
606  // Finally, copy the output operands into the output registers
607  ArrayRef<Register> ResRegs = GetOrCreateVRegs(Call);
608  if (ResRegs.size() != OutputOperands.size()) {
609  LLVM_DEBUG(dbgs() << "Expected the number of output registers to match the "
610  "number of destination registers\n");
611  return false;
612  }
613  for (unsigned int i = 0, e = ResRegs.size(); i < e; i++) {
614  GISelAsmOperandInfo &OpInfo = OutputOperands[i];
615 
616  if (OpInfo.Regs.empty())
617  continue;
618 
619  switch (OpInfo.ConstraintType) {
622  if (OpInfo.Regs.size() > 1) {
623  LLVM_DEBUG(dbgs() << "Output operands with multiple defining "
624  "registers are not supported yet\n");
625  return false;
626  }
627 
628  Register SrcReg = OpInfo.Regs[0];
629  unsigned SrcSize = TRI->getRegSizeInBits(SrcReg, *MRI);
630  if (MRI->getType(ResRegs[i]).getSizeInBits() < SrcSize) {
631  // First copy the non-typed virtual register into a generic virtual
632  // register
633  Register Tmp1Reg =
635  MIRBuilder.buildCopy(Tmp1Reg, SrcReg);
636  // Need to truncate the result of the register
637  MIRBuilder.buildTrunc(ResRegs[i], Tmp1Reg);
638  } else {
639  MIRBuilder.buildCopy(ResRegs[i], SrcReg);
640  }
641  break;
642  }
645  LLVM_DEBUG(
646  dbgs() << "Cannot lower target specific output constraints yet\n");
647  return false;
649  break; // Already handled.
651  LLVM_DEBUG(dbgs() << "Unexpected unknown constraint\n");
652  return false;
653  }
654  }
655 
656  return true;
657 }
658 
660  Value *Val, StringRef Constraint, std::vector<MachineOperand> &Ops,
661  MachineIRBuilder &MIRBuilder) const {
662  if (Constraint.size() > 1)
663  return false;
664 
665  char ConstraintLetter = Constraint[0];
666  switch (ConstraintLetter) {
667  default:
668  return false;
669  case 'i': // Simple Integer or Relocatable Constant
670  case 'n': // immediate integer with a known value.
671  if (ConstantInt *CI = dyn_cast<ConstantInt>(Val)) {
672  assert(CI->getBitWidth() <= 64 &&
673  "expected immediate to fit into 64-bits");
674  // Boolean constants should be zero-extended, others are sign-extended
675  bool IsBool = CI->getBitWidth() == 1;
676  int64_t ExtVal = IsBool ? CI->getZExtValue() : CI->getSExtValue();
677  Ops.push_back(MachineOperand::CreateImm(ExtVal));
678  return true;
679  }
680  return false;
681  }
682 }
i
i
Definition: README.txt:29
llvm::MachineInstrBuilder::addImm
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
Definition: MachineInstrBuilder.h:131
llvm::TargetRegisterClass::getID
unsigned getID() const
Return the register class ID number.
Definition: TargetRegisterInfo.h:71
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
llvm::tgtok::Def
@ Def
Definition: TGLexer.h:50
Reg
unsigned Reg
Definition: MachineSink.cpp:1566
llvm::DataLayout
A parsed version of the target data layout string in and methods for querying it.
Definition: DataLayout.h:112
llvm::MachineRegisterInfo::createVirtualRegister
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
Definition: MachineRegisterInfo.cpp:158
llvm::TargetLowering::ConstraintType
ConstraintType
Definition: TargetLowering.h:4157
llvm::InlineAsm::getAsmString
const std::string & getAsmString() const
Definition: InlineAsm.h:83
llvm::MachineRegisterInfo
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Definition: MachineRegisterInfo.h:52
T
llvm::PointerType::getElementType
Type * getElementType() const
Definition: DerivedTypes.h:673
llvm::Function
Definition: Function.h:61
getRegistersForValue
static void getRegistersForValue(MachineFunction &MF, MachineIRBuilder &MIRBuilder, GISelAsmOperandInfo &OpInfo, GISelAsmOperandInfo &RefOpInfo)
Assign virtual/physical registers for the specified register operand.
Definition: InlineAsmLowering.cpp:85
llvm::InlineAsm::isAlignStack
bool isAlignStack() const
Definition: InlineAsm.h:69
llvm::InlineAsm::ConstraintInfo::isIndirect
bool isIndirect
isIndirect - True if this operand is an indirect operand.
Definition: InlineAsm.h:147
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1168
llvm::MachineIRBuilder::getMRI
MachineRegisterInfo * getMRI()
Getter for MRI.
Definition: MachineIRBuilder.h:280
llvm::InlineAsmLowering::lowerInlineAsm
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 ...
Definition: InlineAsmLowering.cpp:273
llvm::TargetSubtargetInfo::getRegisterInfo
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
Definition: TargetSubtargetInfo.h:124
llvm::InlineAsm::Extra_AsmDialect
@ Extra_AsmDialect
Definition: InlineAsm.h:225
llvm::TargetRegisterInfo
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Definition: TargetRegisterInfo.h:233
llvm::TargetLowering::C_Memory
@ C_Memory
Definition: TargetLowering.h:4160
llvm::Function::getContext
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Definition: Function.cpp:321
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
Module.h
llvm::InlineAsm::Kind_Imm
@ Kind_Imm
Definition: InlineAsm.h:237
llvm::MachineIRBuilder::buildInstrNoInsert
MachineInstrBuilder buildInstrNoInsert(unsigned Opcode)
Build but don't insert <empty> = Opcode <empty>.
Definition: MachineIRBuilder.cpp:40
chooseConstraint
static void chooseConstraint(TargetLowering::AsmOperandInfo &OpInfo, const TargetLowering *TLI)
Definition: InlineAsmLowering.cpp:158
MachineIRBuilder.h
llvm::InlineAsm::Extra_IsConvergent
@ Extra_IsConvergent
Definition: InlineAsm.h:228
TRI
unsigned const TargetRegisterInfo * TRI
Definition: MachineSink.cpp:1567
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
F
#define F(x, y, z)
Definition: MD5.cpp:56
MachineRegisterInfo.h
llvm::ISD::INLINEASM
@ INLINEASM
INLINEASM - Represents an inline asm block.
Definition: ISDOpcodes.h:980
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
TargetLowering.h
llvm::ConstantInt
This is the shared class of boolean and integer constants.
Definition: Constants.h:79
llvm::Type::isSingleValueType
bool isSingleValueType() const
Return true if the type is a valid type for a register in codegen.
Definition: Type.h:259
llvm::MachineFunction::getRegInfo
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Definition: MachineFunction.h:636
InlineAsmLowering.h
llvm::TargetLowering::AsmOperandInfo::ConstraintType
TargetLowering::ConstraintType ConstraintType
Information about the constraint code, e.g.
Definition: TargetLowering.h:4191
llvm::MachineOperand::CreateImm
static MachineOperand CreateImm(int64_t Val)
Definition: MachineOperand.h:773
llvm::InlineAsm::hasSideEffects
bool hasSideEffects() const
Definition: InlineAsm.h:68
llvm::TargetLowering
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
Definition: TargetLowering.h:3189
llvm::LLT::getSizeInBits
TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
Definition: LowLevelTypeImpl.h:153
llvm::TargetLowering::AsmOperandInfo::CallOperandVal
Value * CallOperandVal
If this is the result output operand or a clobber, this is null, otherwise it is the incoming operand...
Definition: TargetLowering.h:4196
llvm::TargetRegisterClass
Definition: TargetRegisterInfo.h:46
Utils.h
llvm::InlineAsm::isInput
@ isInput
Definition: InlineAsm.h:94
llvm::CallBase::isConvergent
bool isConvergent() const
Determine if the invoke is convergent.
Definition: InstrTypes.h:1871
llvm::InlineAsm::isRegDefKind
static bool isRegDefKind(unsigned Flag)
Definition: InlineAsm.h:278
llvm::MCID::Flag
Flag
These should be considered private to the implementation of the MCInstrDesc class.
Definition: MCInstrDesc.h:146
llvm::MachineIRBuilder::getMF
MachineFunction & getMF()
Getter for the function we currently build.
Definition: MachineIRBuilder.h:262
llvm::report_fatal_error
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:140
llvm::TargetLowering::C_Register
@ C_Register
Definition: TargetLowering.h:4158
llvm::TargetLowering::C_Immediate
@ C_Immediate
Definition: TargetLowering.h:4161
Info
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
llvm::RegState::Define
@ Define
Register definition.
Definition: MachineInstrBuilder.h:44
llvm::InlineAsm::getDialect
AsmDialect getDialect() const
Definition: InlineAsm.h:70
llvm::MachineInstrBuilder::addExternalSymbol
const MachineInstrBuilder & addExternalSymbol(const char *FnName, unsigned TargetFlags=0) const
Definition: MachineInstrBuilder.h:184
llvm::InlineAsm::Extra_HasSideEffects
@ Extra_HasSideEffects
Definition: InlineAsm.h:223
llvm::InlineAsm::Kind_RegDefEarlyClobber
@ Kind_RegDefEarlyClobber
Definition: InlineAsm.h:235
llvm::TargetLowering::C_Unknown
@ C_Unknown
Definition: TargetLowering.h:4163
llvm::MachineInstrBuilder::getReg
Register getReg(unsigned Idx) const
Get the register for the operand index.
Definition: MachineInstrBuilder.h:94
llvm::InlineAsm::isMemKind
static bool isMemKind(unsigned Flag)
Definition: InlineAsm.h:280
getConstraintGenerality
static unsigned getConstraintGenerality(TargetLowering::ConstraintType CT)
Return an integer indicating how general CT is.
Definition: InlineAsmLowering.cpp:142
llvm::MachineRegisterInfo::getRegClass
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
Definition: MachineRegisterInfo.h:634
llvm::InlineAsm
Definition: InlineAsm.h:31
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:626
llvm::tgtok::In
@ In
Definition: TGLexer.h:51
llvm::TargetLowering::C_Other
@ C_Other
Definition: TargetLowering.h:4162
llvm::MVT::i64x8
@ i64x8
Definition: MachineValueType.h:273
llvm::MachineIRBuilder
Helper class to build MachineInstr.
Definition: MachineIRBuilder.h:212
llvm::InlineAsm::isRegDefEarlyClobberKind
static bool isRegDefEarlyClobberKind(unsigned Flag)
Definition: InlineAsm.h:281
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:64
llvm::numbers::e
constexpr double e
Definition: MathExtras.h:57
llvm::TargetLowering::ParseConstraints
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...
Definition: TargetLowering.cpp:4659
I
#define I(x, y, z)
Definition: MD5.cpp:59
llvm::InlineAsm::ConstraintInfo::isEarlyClobber
bool isEarlyClobber
isEarlyClobber - "&": output operand writes result before inputs are all read.
Definition: InlineAsm.h:127
Analysis.h
llvm::TargetLowering::AsmOperandInfo
This contains information for each constraint that we are lowering.
Definition: TargetLowering.h:4183
llvm::PointerType
Class to represent pointers.
Definition: DerivedTypes.h:632
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::InlineAsm::ConstraintInfo::Codes
ConstraintCodeVector Codes
Code - The constraint code, either the register name (in braces) or the constraint letter/number.
Definition: InlineAsm.h:151
llvm::MVT::Other
@ Other
Definition: MachineValueType.h:42
function
print Print MemDeps of function
Definition: MemDepPrinter.cpp:83
llvm::InlineAsm::ConstraintInfo::Type
ConstraintPrefix Type
Type - The basic type of the constraint: input/output/clobber.
Definition: InlineAsm.h:123
llvm::MachineRegisterInfo::createGenericVirtualRegister
Register createGenericVirtualRegister(LLT Ty, StringRef Name="")
Create and return a new generic virtual register with low-level type Ty.
Definition: MachineRegisterInfo.cpp:188
llvm::MDNode
Metadata node.
Definition: Metadata.h:906
llvm::TargetLowering::AsmOperandInfo::ConstraintCode
std::string ConstraintCode
This contains the actual string for the code, like "m".
Definition: TargetLowering.h:4187
llvm::MachineFunction
Definition: MachineFunction.h:230
llvm::InlineAsm::getFlagWordForRegClass
static unsigned getFlagWordForRegClass(unsigned InputFlag, unsigned RC)
getFlagWordForRegClass - Augment an existing flag word returned by getFlagWord with the required regi...
Definition: InlineAsm.h:303
llvm::TargetLoweringBase::getSimpleValueType
MVT getSimpleValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Return the MVT corresponding to this LLVM type. See getValueType.
Definition: TargetLowering.h:1449
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: APInt.h:32
DataLayout.h
llvm::RegState::EarlyClobber
@ EarlyClobber
Register definition happens before uses.
Definition: MachineInstrBuilder.h:54
llvm::StructType
Class to represent struct types.
Definition: DerivedTypes.h:213
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm::MachineIRBuilder::insertInstr
MachineInstrBuilder insertInstr(MachineInstrBuilder MIB)
Insert an existing instruction at the insertion point.
Definition: MachineIRBuilder.cpp:45
llvm::InlineAsm::getFlagWord
static unsigned getFlagWord(unsigned Kind, unsigned NumOps)
Definition: InlineAsm.h:272
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:136
llvm::MachineIRBuilder::buildCopy
MachineInstrBuilder buildCopy(const DstOp &Res, const SrcOp &Op)
Build and insert Res = COPY Op.
Definition: MachineIRBuilder.cpp:238
llvm::InlineAsm::Constraint_Unknown
@ Constraint_Unknown
Definition: InlineAsm.h:244
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition: AArch64SLSHardening.cpp:76
llvm::TargetLowering::AsmOperandInfo::getMatchedOperand
unsigned getMatchedOperand() const
If this is an input matching constraint, this method returns the output operand it matches.
Definition: TargetLowering.cpp:4648
llvm::TargetLowering::getRegForInlineAsmConstraint
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
Definition: TargetLowering.cpp:4597
MRI
unsigned const MachineRegisterInfo * MRI
Definition: AArch64AdvSIMDScalarPass.cpp:105
llvm::MachineIRBuilder::buildAnyExt
MachineInstrBuilder buildAnyExt(const DstOp &Res, const SrcOp &Op)
Build and insert Res = G_ANYEXT Op0.
Definition: MachineIRBuilder.cpp:414
llvm::TargetLowering::C_RegisterClass
@ C_RegisterClass
Definition: TargetLowering.h:4159
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
llvm::InlineAsm::getFlagWordForMem
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:315
llvm::InlineAsm::getFlagWordForMatchingOp
static unsigned getFlagWordForMatchingOp(unsigned InputFlag, unsigned MatchedOperandNo)
getFlagWordForMatchingOp - Augment an existing flag word returned by getFlagWord with information ind...
Definition: InlineAsm.h:291
computeConstraintToUse
static void computeConstraintToUse(const TargetLowering *TLI, TargetLowering::AsmOperandInfo &OpInfo)
Definition: InlineAsmLowering.cpp:205
llvm::MachineIRBuilder::buildTrunc
MachineInstrBuilder buildTrunc(const DstOp &Res, const SrcOp &Op)
Build and insert Res = G_TRUNC Op.
Definition: MachineIRBuilder.cpp:737
llvm::TargetRegisterClass::begin
iterator begin() const
begin/end - Return all of the registers in this class.
Definition: TargetRegisterInfo.h:75
llvm::MachineFunction::getFunction
Function & getFunction()
Return the LLVM function that this machine code represents.
Definition: MachineFunction.h:592
llvm::TargetRegisterInfo::getRegSizeInBits
unsigned getRegSizeInBits(const TargetRegisterClass &RC) const
Return the size in bits of a register from class RC.
Definition: TargetRegisterInfo.h:276
uint16_t
get
Should compile to something r4 addze r3 instead we get
Definition: README.txt:24
llvm::InlineAsm::isClobber
@ isClobber
Definition: InlineAsm.h:96
llvm::TargetLowering::AsmOperandInfo::isMatchingInputConstraint
bool isMatchingInputConstraint() const
Return true of this is an input operand that is a matching constraint like "4".
Definition: TargetLowering.cpp:4641
llvm::InlineAsm::Extra_MayStore
@ Extra_MayStore
Definition: InlineAsm.h:227
llvm::TargetLowering::AsmOperandInfo::ConstraintVT
MVT ConstraintVT
The ValueType for the operand value.
Definition: TargetLowering.h:4199
llvm::InlineAsm::Extra_MayLoad
@ Extra_MayLoad
Definition: InlineAsm.h:226
llvm::InlineAsm::Kind_Mem
@ Kind_Mem
Definition: InlineAsm.h:238
llvm::CallBase::getCalledOperand
Value * getCalledOperand() const
Definition: InstrTypes.h:1386
llvm::InlineAsm::Kind_RegUse
@ Kind_RegUse
Definition: InlineAsm.h:233
llvm::InlineAsm::isOutput
@ isOutput
Definition: InlineAsm.h:95
Instructions.h
llvm::TargetSubtargetInfo::getTargetLowering
virtual const TargetLowering * getTargetLowering() const
Definition: TargetSubtargetInfo.h:96
llvm::MachineRegisterInfo::getType
LLT getType(Register Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register.
Definition: MachineRegisterInfo.h:732
llvm::InlineAsm::Kind_Clobber
@ Kind_Clobber
Definition: InlineAsm.h:236
llvm::InlineAsm::getNumOperandRegisters
static unsigned getNumOperandRegisters(unsigned Flag)
getNumOperandRegisters - Extract the number of registers field from the inline asm operand flag.
Definition: InlineAsm.h:339
llvm::MachineInstr::getNumOperands
unsigned getNumOperands() const
Retuns the total number of operands.
Definition: MachineInstr.h:492
llvm::ArrayRef::size
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:165
llvm::TargetLowering::getInlineAsmMemConstraint
virtual unsigned getInlineAsmMemConstraint(StringRef ConstraintCode) const
Definition: TargetLowering.h:4258
llvm::InlineAsm::Kind_RegDef
@ Kind_RegDef
Definition: InlineAsm.h:234
MachineOperand.h
getNumOpRegs
static unsigned getNumOpRegs(const MachineInstr &I, unsigned OpIdx)
Definition: InlineAsmLowering.cpp:235
llvm::TargetLoweringBase::getNumRegisters
virtual unsigned getNumRegisters(LLVMContext &Context, EVT VT, Optional< MVT > RegisterVT=None) const
Return the number of registers that this ValueType will eventually require.
Definition: TargetLowering.h:1498
llvm::CallBase
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Definition: InstrTypes.h:1161
LLVMContext.h
llvm::InlineAsmLowering::lowerAsmOperandForConstraint
virtual bool lowerAsmOperandForConstraint(Value *Val, StringRef Constraint, std::vector< MachineOperand > &Ops, MachineIRBuilder &MIRBuilder) const
Lower the specified operand into the Ops vector.
Definition: InlineAsmLowering.cpp:659
llvm::StringRef::size
LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:157
llvm::LLT::scalar
static LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
Definition: LowLevelTypeImpl.h:43
llvm::InlineAsm::Extra_IsAlignStack
@ Extra_IsAlignStack
Definition: InlineAsm.h:224
llvm::getImplRegState
unsigned getImplRegState(bool B)
Definition: MachineInstrBuilder.h:505
llvm::TargetRegisterClass::end
iterator end() const
Definition: TargetRegisterInfo.h:76
llvm::TargetLoweringBase::getAsmOperandValueType
virtual EVT getAsmOperandValueType(const DataLayout &DL, Type *Ty, bool AllowUnknown=false) const
Definition: TargetLowering.h:1400
llvm::Value
LLVM Value Representation.
Definition: Value.h:75
llvm::TargetLowering::LowerXConstraint
virtual const char * LowerXConstraint(EVT ConstraintVT) const
Try to replace an X constraint, which matches anything, with another that has more specific requireme...
Definition: TargetLowering.cpp:4502
llvm::InlineAsm::ConstraintInfo::hasMatchingInput
bool hasMatchingInput() const
hasMatchingInput - Return true if this is an output constraint that has a matching input constraint.
Definition: InlineAsm.h:137
buildAnyextOrCopy
static bool buildAnyextOrCopy(Register Dst, Register Src, MachineIRBuilder &MIRBuilder)
Definition: InlineAsmLowering.cpp:240
llvm::TargetLowering::getConstraintType
virtual ConstraintType getConstraintType(StringRef Constraint) const
Given a constraint, return the type of constraint it is for this target.
Definition: TargetLowering.cpp:4457
llvm::TargetLowering::AsmOperandInfoVector
std::vector< AsmOperandInfo > AsmOperandInfoVector
Definition: TargetLowering.h:4214
llvm::EVT::getSimpleVT
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition: ValueTypes.h:289