LLVM 23.0.0git
LanaiISelLowering.cpp
Go to the documentation of this file.
1//===-- LanaiISelLowering.cpp - Lanai DAG Lowering Implementation ---------===//
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 file implements the LanaiTargetLowering class.
10//
11//===----------------------------------------------------------------------===//
12
13#include "LanaiISelLowering.h"
14#include "LanaiCondCode.h"
16#include "LanaiSubtarget.h"
19#include "llvm/ADT/APInt.h"
20#include "llvm/ADT/ArrayRef.h"
22#include "llvm/ADT/StringRef.h"
34#include "llvm/IR/CallingConv.h"
36#include "llvm/IR/Function.h"
37#include "llvm/IR/GlobalValue.h"
41#include "llvm/Support/Debug.h"
47#include <cassert>
48#include <cmath>
49#include <cstdint>
50#include <cstdlib>
51#include <utility>
52
53#define DEBUG_TYPE "lanai-lower"
54
55using namespace llvm;
56
57// Limit on number of instructions the lowered multiplication may have before a
58// call to the library function should be generated instead. The threshold is
59// currently set to 14 as this was the smallest threshold that resulted in all
60// constant multiplications being lowered. A threshold of 5 covered all cases
61// except for one multiplication which required 14. mulsi3 requires 16
62// instructions (including the prologue and epilogue but excluding instructions
63// at call site). Until we can inline mulsi3, generating at most 14 instructions
64// will be faster than invoking mulsi3.
66 "lanai-constant-mul-threshold", cl::Hidden,
67 cl::desc("Maximum number of instruction to generate when lowering constant "
68 "multiplication instead of calling library function [default=14]"),
69 cl::init(14));
70
72 const LanaiSubtarget &STI)
73 : TargetLowering(TM, STI) {
74 // Set up the register classes.
75 addRegisterClass(MVT::i32, &Lanai::GPRRegClass);
76
77 // Compute derived properties from the register classes
78 TRI = STI.getRegisterInfo();
80
82
89
94
98
103
110
116
122
127
131
132 // Extended load operations for i1 types must be promoted
133 for (MVT VT : MVT::integer_valuetypes()) {
137 }
138
140
141 // Function alignments
144
145 setJumpIsExpensive(true);
146
147 // TODO: Setting the minimum jump table entries needed before a
148 // switch is transformed to a jump table to 100 to avoid creating jump tables
149 // as this was causing bad performance compared to a large group of if
150 // statements. Re-evaluate this on new benchmarks.
152
153 MaxStoresPerMemset = 16; // For @llvm.memset -> sequence of stores
155 MaxStoresPerMemcpy = 16; // For @llvm.memcpy -> sequence of stores
157 MaxStoresPerMemmove = 16; // For @llvm.memmove -> sequence of stores
159
160 // Booleans always contain 0 or 1.
162
164}
165
167 SelectionDAG &DAG) const {
168 switch (Op.getOpcode()) {
169 case ISD::MUL:
170 return LowerMUL(Op, DAG);
171 case ISD::BR_CC:
172 return LowerBR_CC(Op, DAG);
174 return LowerConstantPool(Op, DAG);
176 return LowerGlobalAddress(Op, DAG);
178 return LowerBlockAddress(Op, DAG);
179 case ISD::JumpTable:
180 return LowerJumpTable(Op, DAG);
181 case ISD::SELECT_CC:
182 return LowerSELECT_CC(Op, DAG);
183 case ISD::SETCC:
184 return LowerSETCC(Op, DAG);
185 case ISD::SHL_PARTS:
186 return LowerSHL_PARTS(Op, DAG);
187 case ISD::SRL_PARTS:
188 return LowerSRL_PARTS(Op, DAG);
189 case ISD::VASTART:
190 return LowerVASTART(Op, DAG);
192 return LowerDYNAMIC_STACKALLOC(Op, DAG);
193 case ISD::RETURNADDR:
194 return LowerRETURNADDR(Op, DAG);
195 case ISD::FRAMEADDR:
196 return LowerFRAMEADDR(Op, DAG);
197 default:
198 llvm_unreachable("unimplemented operand");
199 }
200}
201
202//===----------------------------------------------------------------------===//
203// Lanai Inline Assembly Support
204//===----------------------------------------------------------------------===//
205
207 const char *RegName, LLT /*VT*/,
208 const MachineFunction & /*MF*/) const {
209 // Only unallocatable registers should be matched here.
211 .Case("pc", Lanai::PC)
212 .Case("sp", Lanai::SP)
213 .Case("fp", Lanai::FP)
214 .Case("rr1", Lanai::RR1)
215 .Case("r10", Lanai::R10)
216 .Case("rr2", Lanai::RR2)
217 .Case("r11", Lanai::R11)
218 .Case("rca", Lanai::RCA)
219 .Default(Register());
220 return Reg;
221}
222
223std::pair<unsigned, const TargetRegisterClass *>
225 StringRef Constraint,
226 MVT VT) const {
227 if (Constraint.size() == 1)
228 // GCC Constraint Letters
229 switch (Constraint[0]) {
230 case 'r': // GENERAL_REGS
231 return std::make_pair(0U, &Lanai::GPRRegClass);
232 default:
233 break;
234 }
235
236 return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);
237}
238
239// Examine constraint type and operand type and determine a weight value.
240// This object must already have been set up with the operand type
241// and the current alternative constraint selected.
244 AsmOperandInfo &Info, const char *Constraint) const {
246 Value *CallOperandVal = Info.CallOperandVal;
247 // If we don't have a value, we can't do a match,
248 // but allow it at the lowest weight.
249 if (CallOperandVal == nullptr)
250 return CW_Default;
251 // Look at the constraint type.
252 switch (*Constraint) {
253 case 'I': // signed 16 bit immediate
254 case 'J': // integer zero
255 case 'K': // unsigned 16 bit immediate
256 case 'L': // immediate in the range 0 to 31
257 case 'M': // signed 32 bit immediate where lower 16 bits are 0
258 case 'N': // signed 26 bit immediate
259 case 'O': // integer zero
260 if (isa<ConstantInt>(CallOperandVal))
261 Weight = CW_Constant;
262 break;
263 default:
264 Weight = TargetLowering::getSingleConstraintMatchWeight(Info, Constraint);
265 break;
266 }
267 return Weight;
268}
269
270// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
271// vector. If it is invalid, don't add anything to Ops.
273 SDValue Op, StringRef Constraint, std::vector<SDValue> &Ops,
274 SelectionDAG &DAG) const {
275 SDValue Result;
276
277 // Only support length 1 constraints for now.
278 if (Constraint.size() > 1)
279 return;
280
281 char ConstraintLetter = Constraint[0];
282 switch (ConstraintLetter) {
283 case 'I': // Signed 16 bit constant
284 // If this fails, the parent routine will give an error
286 if (isInt<16>(C->getSExtValue())) {
287 Result = DAG.getTargetConstant(C->getSExtValue(), SDLoc(C),
288 Op.getValueType());
289 break;
290 }
291 }
292 return;
293 case 'J': // integer zero
294 case 'O':
296 if (C->getZExtValue() == 0) {
297 Result = DAG.getTargetConstant(0, SDLoc(C), Op.getValueType());
298 break;
299 }
300 }
301 return;
302 case 'K': // unsigned 16 bit immediate
304 if (isUInt<16>(C->getZExtValue())) {
305 Result = DAG.getTargetConstant(C->getSExtValue(), SDLoc(C),
306 Op.getValueType());
307 break;
308 }
309 }
310 return;
311 case 'L': // immediate in the range 0 to 31
313 if (C->getZExtValue() <= 31) {
314 Result = DAG.getTargetConstant(C->getZExtValue(), SDLoc(C),
315 Op.getValueType());
316 break;
317 }
318 }
319 return;
320 case 'M': // signed 32 bit immediate where lower 16 bits are 0
322 int64_t Val = C->getSExtValue();
323 if ((isInt<32>(Val)) && ((Val & 0xffff) == 0)) {
324 Result = DAG.getTargetConstant(Val, SDLoc(C), Op.getValueType());
325 break;
326 }
327 }
328 return;
329 case 'N': // signed 26 bit immediate
331 int64_t Val = C->getSExtValue();
332 if ((Val >= -33554432) && (Val <= 33554431)) {
333 Result = DAG.getTargetConstant(Val, SDLoc(C), Op.getValueType());
334 break;
335 }
336 }
337 return;
338 default:
339 break; // This will fall through to the generic implementation
340 }
341
342 if (Result.getNode()) {
343 Ops.push_back(Result);
344 return;
345 }
346
348}
349
350//===----------------------------------------------------------------------===//
351// Calling Convention Implementation
352//===----------------------------------------------------------------------===//
353
354#define GET_CALLING_CONV_IMPL
355#include "LanaiGenCallingConv.inc"
356
357static bool CC_Lanai32_VarArg(unsigned ValNo, MVT ValVT, MVT LocVT,
358 CCValAssign::LocInfo LocInfo,
359 ISD::ArgFlagsTy ArgFlags, Type *OrigTy,
360 CCState &State) {
361 // Handle fixed arguments with default CC.
362 // Note: Both the default and fast CC handle VarArg the same and hence the
363 // calling convention of the function is not considered here.
364 if (!ArgFlags.isVarArg())
365 return CC_Lanai32(ValNo, ValVT, LocVT, LocInfo, ArgFlags, OrigTy, State);
366
367 // Promote i8/i16 args to i32
368 if (LocVT == MVT::i8 || LocVT == MVT::i16) {
369 LocVT = MVT::i32;
370 if (ArgFlags.isSExt())
371 LocInfo = CCValAssign::SExt;
372 else if (ArgFlags.isZExt())
373 LocInfo = CCValAssign::ZExt;
374 else
375 LocInfo = CCValAssign::AExt;
376 }
377
378 // VarArgs get passed on stack
379 unsigned Offset = State.AllocateStack(4, Align(4));
380 State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
381 return false;
382}
383
384SDValue LanaiTargetLowering::LowerFormalArguments(
385 SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
386 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
387 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
388 switch (CallConv) {
389 case CallingConv::C:
391 return LowerCCCArguments(Chain, CallConv, IsVarArg, Ins, DL, DAG, InVals);
392 default:
393 report_fatal_error("Unsupported calling convention");
394 }
395}
396
397SDValue LanaiTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
398 SmallVectorImpl<SDValue> &InVals) const {
399 SelectionDAG &DAG = CLI.DAG;
400 SDLoc &DL = CLI.DL;
401 SmallVectorImpl<ISD::OutputArg> &Outs = CLI.Outs;
402 SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
403 SmallVectorImpl<ISD::InputArg> &Ins = CLI.Ins;
404 SDValue Chain = CLI.Chain;
405 SDValue Callee = CLI.Callee;
406 bool &IsTailCall = CLI.IsTailCall;
407 CallingConv::ID CallConv = CLI.CallConv;
408 bool IsVarArg = CLI.IsVarArg;
409
410 // Lanai target does not yet support tail call optimization.
411 IsTailCall = false;
412
413 switch (CallConv) {
415 case CallingConv::C:
416 return LowerCCCCallTo(Chain, Callee, CallConv, IsVarArg, IsTailCall, Outs,
417 OutVals, Ins, DL, DAG, InVals);
418 default:
419 report_fatal_error("Unsupported calling convention");
420 }
421}
422
423// LowerCCCArguments - transform physical registers into virtual registers and
424// generate load operations for arguments places on the stack.
425SDValue LanaiTargetLowering::LowerCCCArguments(
426 SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
427 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
428 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
429 MachineFunction &MF = DAG.getMachineFunction();
430 MachineFrameInfo &MFI = MF.getFrameInfo();
431 MachineRegisterInfo &RegInfo = MF.getRegInfo();
432 LanaiMachineFunctionInfo *LanaiMFI = MF.getInfo<LanaiMachineFunctionInfo>();
433
434 // Assign locations to all of the incoming arguments.
436 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs,
437 *DAG.getContext());
438 if (CallConv == CallingConv::Fast) {
439 CCInfo.AnalyzeFormalArguments(Ins, CC_Lanai32_Fast);
440 } else {
441 CCInfo.AnalyzeFormalArguments(Ins, CC_Lanai32);
442 }
443
444 for (const CCValAssign &VA : ArgLocs) {
445 if (VA.isRegLoc()) {
446 // Arguments passed in registers
447 EVT RegVT = VA.getLocVT();
448 switch (RegVT.getSimpleVT().SimpleTy) {
449 case MVT::i32: {
450 Register VReg = RegInfo.createVirtualRegister(&Lanai::GPRRegClass);
451 RegInfo.addLiveIn(VA.getLocReg(), VReg);
452 SDValue ArgValue = DAG.getCopyFromReg(Chain, DL, VReg, RegVT);
453
454 // If this is an 8/16-bit value, it is really passed promoted to 32
455 // bits. Insert an assert[sz]ext to capture this, then truncate to the
456 // right size.
457 if (VA.getLocInfo() == CCValAssign::SExt)
458 ArgValue = DAG.getNode(ISD::AssertSext, DL, RegVT, ArgValue,
459 DAG.getValueType(VA.getValVT()));
460 else if (VA.getLocInfo() == CCValAssign::ZExt)
461 ArgValue = DAG.getNode(ISD::AssertZext, DL, RegVT, ArgValue,
462 DAG.getValueType(VA.getValVT()));
463
464 if (VA.getLocInfo() != CCValAssign::Full)
465 ArgValue = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), ArgValue);
466
467 InVals.push_back(ArgValue);
468 break;
469 }
470 default:
471 LLVM_DEBUG(dbgs() << "LowerFormalArguments Unhandled argument type: "
472 << RegVT << "\n");
473 llvm_unreachable("unhandled argument type");
474 }
475 } else {
476 // Only arguments passed on the stack should make it here.
477 assert(VA.isMemLoc());
478 // Load the argument to a virtual register
479 unsigned ObjSize = VA.getLocVT().getSizeInBits() / 8;
480 // Check that the argument fits in stack slot
481 if (ObjSize > 4) {
482 errs() << "LowerFormalArguments Unhandled argument type: "
483 << VA.getLocVT() << "\n";
484 }
485 // Create the frame index object for this incoming parameter...
486 int FI = MFI.CreateFixedObject(ObjSize, VA.getLocMemOffset(), true);
487
488 // Create the SelectionDAG nodes corresponding to a load
489 // from this parameter
490 SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);
491 InVals.push_back(DAG.getLoad(
492 VA.getLocVT(), DL, Chain, FIN,
494 }
495 }
496
497 // The Lanai ABI for returning structs by value requires that we copy
498 // the sret argument into rv for the return. Save the argument into
499 // a virtual register so that we can access it from the return points.
500 if (MF.getFunction().hasStructRetAttr()) {
501 Register Reg = LanaiMFI->getSRetReturnReg();
502 if (!Reg) {
504 LanaiMFI->setSRetReturnReg(Reg);
505 }
506 SDValue Copy = DAG.getCopyToReg(DAG.getEntryNode(), DL, Reg, InVals[0]);
507 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Copy, Chain);
508 }
509
510 if (IsVarArg) {
511 // Record the frame index of the first variable argument
512 // which is a value necessary to VASTART.
513 int FI = MFI.CreateFixedObject(4, CCInfo.getStackSize(), true);
514 LanaiMFI->setVarArgsFrameIndex(FI);
515 }
516
517 return Chain;
518}
519
521 CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,
522 const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context,
523 const Type *RetTy) const {
525 CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
526
527 return CCInfo.CheckReturn(Outs, RetCC_Lanai32);
528}
529
531LanaiTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
532 bool IsVarArg,
534 const SmallVectorImpl<SDValue> &OutVals,
535 const SDLoc &DL, SelectionDAG &DAG) const {
536 // CCValAssign - represent the assignment of the return value to a location
538
539 // CCState - Info about the registers and stack slot.
540 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs,
541 *DAG.getContext());
542
543 // Analize return values.
544 CCInfo.AnalyzeReturn(Outs, RetCC_Lanai32);
545
546 SDValue Glue;
547 SmallVector<SDValue, 4> RetOps(1, Chain);
548
549 // Copy the result values into the output registers.
550 for (unsigned i = 0; i != RVLocs.size(); ++i) {
551 CCValAssign &VA = RVLocs[i];
552 assert(VA.isRegLoc() && "Can only return in registers!");
553
554 Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), OutVals[i], Glue);
555
556 // Guarantee that all emitted copies are stuck together with flags.
557 Glue = Chain.getValue(1);
558 RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
559 }
560
561 // The Lanai ABI for returning structs by value requires that we copy
562 // the sret argument into rv for the return. We saved the argument into
563 // a virtual register in the entry block, so now we copy the value out
564 // and into rv.
568 Register Reg = LanaiMFI->getSRetReturnReg();
569 assert(Reg &&
570 "SRetReturnReg should have been set in LowerFormalArguments().");
571 SDValue Val =
572 DAG.getCopyFromReg(Chain, DL, Reg, getPointerTy(DAG.getDataLayout()));
573
574 Chain = DAG.getCopyToReg(Chain, DL, Lanai::RV, Val, Glue);
575 Glue = Chain.getValue(1);
576 RetOps.push_back(
577 DAG.getRegister(Lanai::RV, getPointerTy(DAG.getDataLayout())));
578 }
579
580 RetOps[0] = Chain; // Update chain
581
582 unsigned Opc = LanaiISD::RET_GLUE;
583 if (Glue.getNode())
584 RetOps.push_back(Glue);
585
586 // Return Void
587 return DAG.getNode(Opc, DL, MVT::Other,
588 ArrayRef<SDValue>(&RetOps[0], RetOps.size()));
589}
590
591// LowerCCCCallTo - functions arguments are copied from virtual regs to
592// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted.
593SDValue LanaiTargetLowering::LowerCCCCallTo(
594 SDValue Chain, SDValue Callee, CallingConv::ID CallConv, bool IsVarArg,
595 bool /*IsTailCall*/, const SmallVectorImpl<ISD::OutputArg> &Outs,
596 const SmallVectorImpl<SDValue> &OutVals,
597 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
598 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
599 // Analyze operands of the call, assigning locations to each operand.
601 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs,
602 *DAG.getContext());
603 GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee);
604 MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo();
605
606 if (IsVarArg) {
607 CCInfo.AnalyzeCallOperands(Outs, CC_Lanai32_VarArg);
608 } else {
609 if (CallConv == CallingConv::Fast)
610 CCInfo.AnalyzeCallOperands(Outs, CC_Lanai32_Fast);
611 else
612 CCInfo.AnalyzeCallOperands(Outs, CC_Lanai32);
613 }
614
615 // Get a count of how many bytes are to be pushed on the stack.
616 unsigned NumBytes = CCInfo.getStackSize();
617
618 // Create local copies for byval args.
619 SmallVector<SDValue, 8> ByValArgs;
620 for (unsigned I = 0, E = Outs.size(); I != E; ++I) {
621 ISD::ArgFlagsTy Flags = Outs[I].Flags;
622 if (!Flags.isByVal())
623 continue;
624
625 SDValue Arg = OutVals[I];
626 unsigned Size = Flags.getByValSize();
627 Align Alignment = Flags.getNonZeroByValAlign();
628
629 int FI = MFI.CreateStackObject(Size, Alignment, false);
630 SDValue FIPtr = DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout()));
631 SDValue SizeNode = DAG.getConstant(Size, DL, MVT::i32);
632
633 Chain = DAG.getMemcpy(Chain, DL, FIPtr, Arg, SizeNode, Alignment, Alignment,
634 /*IsVolatile=*/false,
635 /*AlwaysInline=*/false,
636 /*CI=*/nullptr, std::nullopt, MachinePointerInfo(),
637 MachinePointerInfo());
638 ByValArgs.push_back(FIPtr);
639 }
640
641 Chain = DAG.getCALLSEQ_START(Chain, NumBytes, 0, DL);
642
644 SmallVector<SDValue, 12> MemOpChains;
646
647 // Walk the register/memloc assignments, inserting copies/loads.
648 for (unsigned I = 0, J = 0, E = ArgLocs.size(); I != E; ++I) {
649 CCValAssign &VA = ArgLocs[I];
650 SDValue Arg = OutVals[I];
651 ISD::ArgFlagsTy Flags = Outs[I].Flags;
652
653 // Promote the value if needed.
654 switch (VA.getLocInfo()) {
656 break;
658 Arg = DAG.getNode(ISD::SIGN_EXTEND, DL, VA.getLocVT(), Arg);
659 break;
661 Arg = DAG.getNode(ISD::ZERO_EXTEND, DL, VA.getLocVT(), Arg);
662 break;
664 Arg = DAG.getNode(ISD::ANY_EXTEND, DL, VA.getLocVT(), Arg);
665 break;
666 default:
667 llvm_unreachable("Unknown loc info!");
668 }
669
670 // Use local copy if it is a byval arg.
671 if (Flags.isByVal())
672 Arg = ByValArgs[J++];
673
674 // Arguments that can be passed on register must be kept at RegsToPass
675 // vector
676 if (VA.isRegLoc()) {
677 RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
678 } else {
679 assert(VA.isMemLoc());
680
681 if (StackPtr.getNode() == nullptr)
682 StackPtr = DAG.getCopyFromReg(Chain, DL, Lanai::SP,
684
685 SDValue PtrOff =
686 DAG.getNode(ISD::ADD, DL, getPointerTy(DAG.getDataLayout()), StackPtr,
688
689 MemOpChains.push_back(
690 DAG.getStore(Chain, DL, Arg, PtrOff, MachinePointerInfo()));
691 }
692 }
693
694 // Transform all store nodes into one single node because all store nodes are
695 // independent of each other.
696 if (!MemOpChains.empty())
697 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other,
698 ArrayRef<SDValue>(&MemOpChains[0], MemOpChains.size()));
699
700 SDValue InGlue;
701
702 // Build a sequence of copy-to-reg nodes chained together with token chain and
703 // flag operands which copy the outgoing args into registers. The InGlue in
704 // necessary since all emitted instructions must be stuck together.
705 for (const auto &[Reg, N] : RegsToPass) {
706 Chain = DAG.getCopyToReg(Chain, DL, Reg, N, InGlue);
707 InGlue = Chain.getValue(1);
708 }
709
710 // If the callee is a GlobalAddress node (quite common, every direct call is)
711 // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
712 // Likewise ExternalSymbol -> TargetExternalSymbol.
713 uint8_t OpFlag = LanaiII::MO_NO_FLAG;
714 if (G) {
716 G->getGlobal(), DL, getPointerTy(DAG.getDataLayout()), 0, OpFlag);
717 } else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee)) {
719 E->getSymbol(), getPointerTy(DAG.getDataLayout()), OpFlag);
720 }
721
722 // Returns a chain & a flag for retval copy to use.
723 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
725 Ops.push_back(Chain);
726 Ops.push_back(Callee);
727
728 // Add a register mask operand representing the call-preserved registers.
729 // TODO: Should return-twice functions be handled?
730 const uint32_t *Mask =
731 TRI->getCallPreservedMask(DAG.getMachineFunction(), CallConv);
732 assert(Mask && "Missing call preserved mask for calling convention");
733 Ops.push_back(DAG.getRegisterMask(Mask));
734
735 // Add argument registers to the end of the list so that they are
736 // known live into the call.
737 for (const auto &[Reg, N] : RegsToPass)
738 Ops.push_back(DAG.getRegister(Reg, N.getValueType()));
739
740 if (InGlue.getNode())
741 Ops.push_back(InGlue);
742
743 Chain = DAG.getNode(LanaiISD::CALL, DL, NodeTys,
744 ArrayRef<SDValue>(&Ops[0], Ops.size()));
745 InGlue = Chain.getValue(1);
746
747 // Create the CALLSEQ_END node.
748 Chain = DAG.getCALLSEQ_END(Chain, NumBytes, 0, InGlue, DL);
749 InGlue = Chain.getValue(1);
750
751 // Handle result values, copying them out of physregs into vregs that we
752 // return.
753 return LowerCallResult(Chain, InGlue, CallConv, IsVarArg, Ins, DL, DAG,
754 InVals);
755}
756
757// LowerCallResult - Lower the result values of a call into the
758// appropriate copies out of appropriate physical registers.
759SDValue LanaiTargetLowering::LowerCallResult(
760 SDValue Chain, SDValue InGlue, CallingConv::ID CallConv, bool IsVarArg,
761 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
762 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
763 // Assign locations to each value returned by this call.
765 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs,
766 *DAG.getContext());
767
768 CCInfo.AnalyzeCallResult(Ins, RetCC_Lanai32);
769
770 // Copy all of the result registers out of their specified physreg.
771 for (unsigned I = 0; I != RVLocs.size(); ++I) {
772 Chain = DAG.getCopyFromReg(Chain, DL, RVLocs[I].getLocReg(),
773 RVLocs[I].getValVT(), InGlue)
774 .getValue(1);
775 InGlue = Chain.getValue(2);
776 InVals.push_back(Chain.getValue(0));
777 }
778
779 return Chain;
780}
781
782//===----------------------------------------------------------------------===//
783// Custom Lowerings
784//===----------------------------------------------------------------------===//
785
787 SDValue &RHS, SelectionDAG &DAG) {
788 ISD::CondCode SetCCOpcode = cast<CondCodeSDNode>(CC)->get();
789
790 // For integer, only the SETEQ, SETNE, SETLT, SETLE, SETGT, SETGE, SETULT,
791 // SETULE, SETUGT, and SETUGE opcodes are used (see CodeGen/ISDOpcodes.h)
792 // and Lanai only supports integer comparisons, so only provide definitions
793 // for them.
794 switch (SetCCOpcode) {
795 case ISD::SETEQ:
796 return LPCC::ICC_EQ;
797 case ISD::SETGT:
799 if (RHSC->getZExtValue() == 0xFFFFFFFF) {
800 // X > -1 -> X >= 0 -> is_plus(X)
801 RHS = DAG.getConstant(0, DL, RHS.getValueType());
802 return LPCC::ICC_PL;
803 }
804 return LPCC::ICC_GT;
805 case ISD::SETUGT:
806 return LPCC::ICC_UGT;
807 case ISD::SETLT:
809 if (RHSC->getZExtValue() == 0)
810 // X < 0 -> is_minus(X)
811 return LPCC::ICC_MI;
812 return LPCC::ICC_LT;
813 case ISD::SETULT:
814 return LPCC::ICC_ULT;
815 case ISD::SETLE:
817 if (RHSC->getZExtValue() == 0xFFFFFFFF) {
818 // X <= -1 -> X < 0 -> is_minus(X)
819 RHS = DAG.getConstant(0, DL, RHS.getValueType());
820 return LPCC::ICC_MI;
821 }
822 return LPCC::ICC_LE;
823 case ISD::SETULE:
824 return LPCC::ICC_ULE;
825 case ISD::SETGE:
827 if (RHSC->getZExtValue() == 0)
828 // X >= 0 -> is_plus(X)
829 return LPCC::ICC_PL;
830 return LPCC::ICC_GE;
831 case ISD::SETUGE:
832 return LPCC::ICC_UGE;
833 case ISD::SETNE:
834 return LPCC::ICC_NE;
835 case ISD::SETONE:
836 case ISD::SETUNE:
837 case ISD::SETOGE:
838 case ISD::SETOLE:
839 case ISD::SETOLT:
840 case ISD::SETOGT:
841 case ISD::SETOEQ:
842 case ISD::SETUEQ:
843 case ISD::SETO:
844 case ISD::SETUO:
845 llvm_unreachable("Unsupported comparison.");
846 default:
847 llvm_unreachable("Unknown integer condition code!");
848 }
849}
850
852 SDValue Chain = Op.getOperand(0);
853 SDValue Cond = Op.getOperand(1);
854 SDValue LHS = Op.getOperand(2);
855 SDValue RHS = Op.getOperand(3);
856 SDValue Dest = Op.getOperand(4);
857 SDLoc DL(Op);
858
859 LPCC::CondCode CC = IntCondCCodeToICC(Cond, DL, RHS, DAG);
860 SDValue TargetCC = DAG.getConstant(CC, DL, MVT::i32);
861 SDValue Glue = DAG.getNode(LanaiISD::SET_FLAG, DL, MVT::Glue, LHS, RHS);
862
863 return DAG.getNode(LanaiISD::BR_CC, DL, Op.getValueType(), Chain, Dest,
864 TargetCC, Glue);
865}
866
868 EVT VT = Op->getValueType(0);
869 if (VT != MVT::i32)
870 return SDValue();
871
872 ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op->getOperand(1));
873 if (!C)
874 return SDValue();
875
876 int64_t MulAmt = C->getSExtValue();
877 int32_t HighestOne = -1;
878 uint32_t NonzeroEntries = 0;
879 int SignedDigit[32] = {0};
880
881 // Convert to non-adjacent form (NAF) signed-digit representation.
882 // NAF is a signed-digit form where no adjacent digits are non-zero. It is the
883 // minimal Hamming weight representation of a number (on average 1/3 of the
884 // digits will be non-zero vs 1/2 for regular binary representation). And as
885 // the non-zero digits will be the only digits contributing to the instruction
886 // count, this is desirable. The next loop converts it to NAF (following the
887 // approach in 'Guide to Elliptic Curve Cryptography' [ISBN: 038795273X]) by
888 // choosing the non-zero coefficients such that the resulting quotient is
889 // divisible by 2 which will cause the next coefficient to be zero.
890 int64_t E = std::abs(MulAmt);
891 int S = (MulAmt < 0 ? -1 : 1);
892 int I = 0;
893 while (E > 0) {
894 int ZI = 0;
895 if (E % 2 == 1) {
896 ZI = 2 - (E % 4);
897 if (ZI != 0)
898 ++NonzeroEntries;
899 }
900 SignedDigit[I] = S * ZI;
901 if (SignedDigit[I] == 1)
902 HighestOne = I;
903 E = (E - ZI) / 2;
904 ++I;
905 }
906
907 // Compute number of instructions required. Due to differences in lowering
908 // between the different processors this count is not exact.
909 // Start by assuming a shift and a add/sub for every non-zero entry (hence
910 // every non-zero entry requires 1 shift and 1 add/sub except for the first
911 // entry).
912 int32_t InstrRequired = 2 * NonzeroEntries - 1;
913 // Correct possible over-adding due to shift by 0 (which is not emitted).
914 if (std::abs(MulAmt) % 2 == 1)
915 --InstrRequired;
916 // Return if the form generated would exceed the instruction threshold.
917 if (InstrRequired > LanaiLowerConstantMulThreshold)
918 return SDValue();
919
920 SDValue Res;
921 SDLoc DL(Op);
922 SDValue V = Op->getOperand(0);
923
924 // Initialize the running sum. Set the running sum to the maximal shifted
925 // positive value (i.e., largest i such that zi == 1 and MulAmt has V<<i as a
926 // term NAF).
927 if (HighestOne == -1)
928 Res = DAG.getConstant(0, DL, MVT::i32);
929 else {
930 Res = DAG.getNode(ISD::SHL, DL, VT, V,
931 DAG.getConstant(HighestOne, DL, MVT::i32));
932 SignedDigit[HighestOne] = 0;
933 }
934
935 // Assemble multiplication from shift, add, sub using NAF form and running
936 // sum.
937 for (unsigned int I = 0; I < std::size(SignedDigit); ++I) {
938 if (SignedDigit[I] == 0)
939 continue;
940
941 // Shifted multiplicand (v<<i).
942 SDValue Op =
943 DAG.getNode(ISD::SHL, DL, VT, V, DAG.getConstant(I, DL, MVT::i32));
944 if (SignedDigit[I] == 1)
945 Res = DAG.getNode(ISD::ADD, DL, VT, Res, Op);
946 else if (SignedDigit[I] == -1)
947 Res = DAG.getNode(ISD::SUB, DL, VT, Res, Op);
948 }
949 return Res;
950}
951
953 SDValue LHS = Op.getOperand(0);
954 SDValue RHS = Op.getOperand(1);
955 SDValue Cond = Op.getOperand(2);
956 SDLoc DL(Op);
957
958 LPCC::CondCode CC = IntCondCCodeToICC(Cond, DL, RHS, DAG);
959 SDValue TargetCC = DAG.getConstant(CC, DL, MVT::i32);
960 SDValue Glue = DAG.getNode(LanaiISD::SET_FLAG, DL, MVT::Glue, LHS, RHS);
961
962 return DAG.getNode(LanaiISD::SETCC, DL, Op.getValueType(), TargetCC, Glue);
963}
964
966 SelectionDAG &DAG) const {
967 SDValue LHS = Op.getOperand(0);
968 SDValue RHS = Op.getOperand(1);
969 SDValue TrueV = Op.getOperand(2);
970 SDValue FalseV = Op.getOperand(3);
971 SDValue Cond = Op.getOperand(4);
972 SDLoc DL(Op);
973
974 LPCC::CondCode CC = IntCondCCodeToICC(Cond, DL, RHS, DAG);
975 SDValue TargetCC = DAG.getConstant(CC, DL, MVT::i32);
976 SDValue Glue = DAG.getNode(LanaiISD::SET_FLAG, DL, MVT::Glue, LHS, RHS);
977
978 return DAG.getNode(LanaiISD::SELECT_CC, DL, Op.getValueType(), TrueV, FalseV,
979 TargetCC, Glue);
980}
981
985
986 SDLoc DL(Op);
987 SDValue FI = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(),
989
990 // vastart just stores the address of the VarArgsFrameIndex slot into the
991 // memory location argument.
992 const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
993 return DAG.getStore(Op.getOperand(0), DL, FI, Op.getOperand(1),
995}
996
998 SelectionDAG &DAG) const {
999 SDValue Chain = Op.getOperand(0);
1000 SDValue Size = Op.getOperand(1);
1001 SDLoc DL(Op);
1002
1004
1005 // Get a reference to the stack pointer.
1006 SDValue StackPointer = DAG.getCopyFromReg(Chain, DL, SPReg, MVT::i32);
1007
1008 // Subtract the dynamic size from the actual stack size to
1009 // obtain the new stack size.
1010 SDValue Sub = DAG.getNode(ISD::SUB, DL, MVT::i32, StackPointer, Size);
1011
1012 // For Lanai, the outgoing memory arguments area should be on top of the
1013 // alloca area on the stack i.e., the outgoing memory arguments should be
1014 // at a lower address than the alloca area. Move the alloca area down the
1015 // stack by adding back the space reserved for outgoing arguments to SP
1016 // here.
1017 //
1018 // We do not know what the size of the outgoing args is at this point.
1019 // So, we add a pseudo instruction ADJDYNALLOC that will adjust the
1020 // stack pointer. We replace this instruction with on that has the correct,
1021 // known offset in emitPrologue().
1022 SDValue ArgAdjust = DAG.getNode(LanaiISD::ADJDYNALLOC, DL, MVT::i32, Sub);
1023
1024 // The Sub result contains the new stack start address, so it
1025 // must be placed in the stack pointer register.
1026 SDValue CopyChain = DAG.getCopyToReg(Chain, DL, SPReg, Sub);
1027
1028 SDValue Ops[2] = {ArgAdjust, CopyChain};
1029 return DAG.getMergeValues(Ops, DL);
1030}
1031
1033 SelectionDAG &DAG) const {
1035 MachineFrameInfo &MFI = MF.getFrameInfo();
1036 MFI.setReturnAddressIsTaken(true);
1037
1038 EVT VT = Op.getValueType();
1039 SDLoc DL(Op);
1040 unsigned Depth = Op.getConstantOperandVal(0);
1041 if (Depth) {
1042 SDValue FrameAddr = LowerFRAMEADDR(Op, DAG);
1043 const unsigned Offset = -4;
1044 SDValue Ptr = DAG.getNode(ISD::ADD, DL, VT, FrameAddr,
1046 return DAG.getLoad(VT, DL, DAG.getEntryNode(), Ptr, MachinePointerInfo());
1047 }
1048
1049 // Return the link register, which contains the return address.
1050 // Mark it an implicit live-in.
1051 Register Reg = MF.addLiveIn(TRI->getRARegister(), getRegClassFor(MVT::i32));
1052 return DAG.getCopyFromReg(DAG.getEntryNode(), DL, Reg, VT);
1053}
1054
1056 SelectionDAG &DAG) const {
1058 MFI.setFrameAddressIsTaken(true);
1059
1060 EVT VT = Op.getValueType();
1061 SDLoc DL(Op);
1062 SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), DL, Lanai::FP, VT);
1063 unsigned Depth = Op.getConstantOperandVal(0);
1064 while (Depth--) {
1065 const unsigned Offset = -8;
1066 SDValue Ptr = DAG.getNode(ISD::ADD, DL, VT, FrameAddr,
1068 FrameAddr =
1069 DAG.getLoad(VT, DL, DAG.getEntryNode(), Ptr, MachinePointerInfo());
1070 }
1071 return FrameAddr;
1072}
1073
1075 SelectionDAG &DAG) const {
1076 SDLoc DL(Op);
1078 const Constant *C = N->getConstVal();
1079 const LanaiTargetObjectFile *TLOF =
1080 static_cast<const LanaiTargetObjectFile *>(
1082
1083 // If the code model is small or constant will be placed in the small section,
1084 // then assume address will fit in 21-bits.
1087 SDValue Small = DAG.getTargetConstantPool(
1088 C, MVT::i32, N->getAlign(), N->getOffset(), LanaiII::MO_NO_FLAG);
1089 return DAG.getNode(ISD::OR, DL, MVT::i32,
1090 DAG.getRegister(Lanai::R0, MVT::i32),
1091 DAG.getNode(LanaiISD::SMALL, DL, MVT::i32, Small));
1092 } else {
1093 uint8_t OpFlagHi = LanaiII::MO_ABS_HI;
1094 uint8_t OpFlagLo = LanaiII::MO_ABS_LO;
1095
1096 SDValue Hi = DAG.getTargetConstantPool(C, MVT::i32, N->getAlign(),
1097 N->getOffset(), OpFlagHi);
1098 SDValue Lo = DAG.getTargetConstantPool(C, MVT::i32, N->getAlign(),
1099 N->getOffset(), OpFlagLo);
1100 Hi = DAG.getNode(LanaiISD::HI, DL, MVT::i32, Hi);
1101 Lo = DAG.getNode(LanaiISD::LO, DL, MVT::i32, Lo);
1102 SDValue Result = DAG.getNode(ISD::OR, DL, MVT::i32, Hi, Lo);
1103 return Result;
1104 }
1105}
1106
1108 SelectionDAG &DAG) const {
1109 SDLoc DL(Op);
1110 const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
1111 int64_t Offset = cast<GlobalAddressSDNode>(Op)->getOffset();
1112
1113 const LanaiTargetObjectFile *TLOF =
1114 static_cast<const LanaiTargetObjectFile *>(
1116
1117 // If the code model is small or global variable will be placed in the small
1118 // section, then assume address will fit in 21-bits.
1119 const GlobalObject *GO = GV->getAliaseeObject();
1120 if (TLOF->isGlobalInSmallSection(GO, getTargetMachine())) {
1121 SDValue Small = DAG.getTargetGlobalAddress(
1123 return DAG.getNode(ISD::OR, DL, MVT::i32,
1124 DAG.getRegister(Lanai::R0, MVT::i32),
1125 DAG.getNode(LanaiISD::SMALL, DL, MVT::i32, Small));
1126 } else {
1127 uint8_t OpFlagHi = LanaiII::MO_ABS_HI;
1128 uint8_t OpFlagLo = LanaiII::MO_ABS_LO;
1129
1130 // Create the TargetGlobalAddress node, folding in the constant offset.
1132 GV, DL, getPointerTy(DAG.getDataLayout()), Offset, OpFlagHi);
1134 GV, DL, getPointerTy(DAG.getDataLayout()), Offset, OpFlagLo);
1135 Hi = DAG.getNode(LanaiISD::HI, DL, MVT::i32, Hi);
1136 Lo = DAG.getNode(LanaiISD::LO, DL, MVT::i32, Lo);
1137 return DAG.getNode(ISD::OR, DL, MVT::i32, Hi, Lo);
1138 }
1139}
1140
1142 SelectionDAG &DAG) const {
1143 SDLoc DL(Op);
1144 const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();
1145
1146 uint8_t OpFlagHi = LanaiII::MO_ABS_HI;
1147 uint8_t OpFlagLo = LanaiII::MO_ABS_LO;
1148
1149 SDValue Hi = DAG.getBlockAddress(BA, MVT::i32, true, OpFlagHi);
1150 SDValue Lo = DAG.getBlockAddress(BA, MVT::i32, true, OpFlagLo);
1151 Hi = DAG.getNode(LanaiISD::HI, DL, MVT::i32, Hi);
1152 Lo = DAG.getNode(LanaiISD::LO, DL, MVT::i32, Lo);
1153 SDValue Result = DAG.getNode(ISD::OR, DL, MVT::i32, Hi, Lo);
1154 return Result;
1155}
1156
1158 SelectionDAG &DAG) const {
1159 SDLoc DL(Op);
1161
1162 // If the code model is small assume address will fit in 21-bits.
1164 SDValue Small = DAG.getTargetJumpTable(
1166 return DAG.getNode(ISD::OR, DL, MVT::i32,
1167 DAG.getRegister(Lanai::R0, MVT::i32),
1168 DAG.getNode(LanaiISD::SMALL, DL, MVT::i32, Small));
1169 } else {
1170 uint8_t OpFlagHi = LanaiII::MO_ABS_HI;
1171 uint8_t OpFlagLo = LanaiII::MO_ABS_LO;
1172
1174 JT->getIndex(), getPointerTy(DAG.getDataLayout()), OpFlagHi);
1176 JT->getIndex(), getPointerTy(DAG.getDataLayout()), OpFlagLo);
1177 Hi = DAG.getNode(LanaiISD::HI, DL, MVT::i32, Hi);
1178 Lo = DAG.getNode(LanaiISD::LO, DL, MVT::i32, Lo);
1179 SDValue Result = DAG.getNode(ISD::OR, DL, MVT::i32, Hi, Lo);
1180 return Result;
1181 }
1182}
1183
1185 SelectionDAG &DAG) const {
1186 EVT VT = Op.getValueType();
1187 unsigned VTBits = VT.getSizeInBits();
1188 SDLoc dl(Op);
1189 assert(Op.getNumOperands() == 3 && "Unexpected SHL!");
1190 SDValue ShOpLo = Op.getOperand(0);
1191 SDValue ShOpHi = Op.getOperand(1);
1192 SDValue ShAmt = Op.getOperand(2);
1193
1194 // Performs the following for (ShOpLo + (ShOpHi << 32)) << ShAmt:
1195 // LoBitsForHi = (ShAmt == 0) ? 0 : (ShOpLo >> (32-ShAmt))
1196 // HiBitsForHi = ShOpHi << ShAmt
1197 // Hi = (ShAmt >= 32) ? (ShOpLo << (ShAmt-32)) : (LoBitsForHi | HiBitsForHi)
1198 // Lo = (ShAmt >= 32) ? 0 : (ShOpLo << ShAmt)
1199 // return (Hi << 32) | Lo;
1200
1201 SDValue RevShAmt = DAG.getNode(ISD::SUB, dl, MVT::i32,
1202 DAG.getConstant(VTBits, dl, MVT::i32), ShAmt);
1203 SDValue LoBitsForHi = DAG.getNode(ISD::SRL, dl, VT, ShOpLo, RevShAmt);
1204
1205 // If ShAmt == 0, we just calculated "(SRL ShOpLo, 32)" which is "undef". We
1206 // wanted 0, so CSEL it directly.
1207 SDValue Zero = DAG.getConstant(0, dl, MVT::i32);
1208 SDValue SetCC = DAG.getSetCC(dl, MVT::i32, ShAmt, Zero, ISD::SETEQ);
1209 LoBitsForHi = DAG.getSelect(dl, MVT::i32, SetCC, Zero, LoBitsForHi);
1210
1211 SDValue ExtraShAmt = DAG.getNode(ISD::SUB, dl, MVT::i32, ShAmt,
1212 DAG.getConstant(VTBits, dl, MVT::i32));
1213 SDValue HiBitsForHi = DAG.getNode(ISD::SHL, dl, VT, ShOpHi, ShAmt);
1214 SDValue HiForNormalShift =
1215 DAG.getNode(ISD::OR, dl, VT, LoBitsForHi, HiBitsForHi);
1216
1217 SDValue HiForBigShift = DAG.getNode(ISD::SHL, dl, VT, ShOpLo, ExtraShAmt);
1218
1219 SetCC = DAG.getSetCC(dl, MVT::i32, ExtraShAmt, Zero, ISD::SETGE);
1220 SDValue Hi =
1221 DAG.getSelect(dl, MVT::i32, SetCC, HiForBigShift, HiForNormalShift);
1222
1223 // Lanai shifts of larger than register sizes are wrapped rather than
1224 // clamped, so we can't just emit "lo << b" if b is too big.
1225 SDValue LoForNormalShift = DAG.getNode(ISD::SHL, dl, VT, ShOpLo, ShAmt);
1226 SDValue Lo = DAG.getSelect(
1227 dl, MVT::i32, SetCC, DAG.getConstant(0, dl, MVT::i32), LoForNormalShift);
1228
1229 SDValue Ops[2] = {Lo, Hi};
1230 return DAG.getMergeValues(Ops, dl);
1231}
1232
1234 SelectionDAG &DAG) const {
1235 MVT VT = Op.getSimpleValueType();
1236 unsigned VTBits = VT.getSizeInBits();
1237 SDLoc dl(Op);
1238 SDValue ShOpLo = Op.getOperand(0);
1239 SDValue ShOpHi = Op.getOperand(1);
1240 SDValue ShAmt = Op.getOperand(2);
1241
1242 // Performs the following for a >> b:
1243 // unsigned r_high = a_high >> b;
1244 // r_high = (32 - b <= 0) ? 0 : r_high;
1245 //
1246 // unsigned r_low = a_low >> b;
1247 // r_low = (32 - b <= 0) ? r_high : r_low;
1248 // r_low = (b == 0) ? r_low : r_low | (a_high << (32 - b));
1249 // return (unsigned long long)r_high << 32 | r_low;
1250 // Note: This takes advantage of Lanai's shift behavior to avoid needing to
1251 // mask the shift amount.
1252
1253 SDValue Zero = DAG.getConstant(0, dl, MVT::i32);
1254 SDValue NegatedPlus32 = DAG.getNode(
1255 ISD::SUB, dl, MVT::i32, DAG.getConstant(VTBits, dl, MVT::i32), ShAmt);
1256 SDValue SetCC = DAG.getSetCC(dl, MVT::i32, NegatedPlus32, Zero, ISD::SETLE);
1257
1258 SDValue Hi = DAG.getNode(ISD::SRL, dl, MVT::i32, ShOpHi, ShAmt);
1259 Hi = DAG.getSelect(dl, MVT::i32, SetCC, Zero, Hi);
1260
1261 SDValue Lo = DAG.getNode(ISD::SRL, dl, MVT::i32, ShOpLo, ShAmt);
1262 Lo = DAG.getSelect(dl, MVT::i32, SetCC, Hi, Lo);
1263 SDValue CarryBits =
1264 DAG.getNode(ISD::SHL, dl, MVT::i32, ShOpHi, NegatedPlus32);
1265 SDValue ShiftIsZero = DAG.getSetCC(dl, MVT::i32, ShAmt, Zero, ISD::SETEQ);
1266 Lo = DAG.getSelect(dl, MVT::i32, ShiftIsZero, Lo,
1267 DAG.getNode(ISD::OR, dl, MVT::i32, Lo, CarryBits));
1268
1269 SDValue Ops[2] = {Lo, Hi};
1270 return DAG.getMergeValues(Ops, dl);
1271}
1272
1273// Helper function that checks if N is a null or all ones constant.
1274static inline bool isZeroOrAllOnes(SDValue N, bool AllOnes) {
1276}
1277
1278// Return true if N is conditionally 0 or all ones.
1279// Detects these expressions where cc is an i1 value:
1280//
1281// (select cc 0, y) [AllOnes=0]
1282// (select cc y, 0) [AllOnes=0]
1283// (zext cc) [AllOnes=0]
1284// (sext cc) [AllOnes=0/1]
1285// (select cc -1, y) [AllOnes=1]
1286// (select cc y, -1) [AllOnes=1]
1287//
1288// * AllOnes determines whether to check for an all zero (AllOnes false) or an
1289// all ones operand (AllOnes true).
1290// * Invert is set when N is the all zero/ones constant when CC is false.
1291// * OtherOp is set to the alternative value of N.
1292//
1293// For example, for (select cc X, Y) and AllOnes = 0 if:
1294// * X = 0, Invert = False and OtherOp = Y
1295// * Y = 0, Invert = True and OtherOp = X
1297 bool &Invert, SDValue &OtherOp,
1298 SelectionDAG &DAG) {
1299 switch (N->getOpcode()) {
1300 default:
1301 return false;
1302 case ISD::SELECT: {
1303 CC = N->getOperand(0);
1304 SDValue N1 = N->getOperand(1);
1305 SDValue N2 = N->getOperand(2);
1306 if (isZeroOrAllOnes(N1, AllOnes)) {
1307 Invert = false;
1308 OtherOp = N2;
1309 return true;
1310 }
1311 if (isZeroOrAllOnes(N2, AllOnes)) {
1312 Invert = true;
1313 OtherOp = N1;
1314 return true;
1315 }
1316 return false;
1317 }
1318 case ISD::ZERO_EXTEND: {
1319 // (zext cc) can never be the all ones value.
1320 if (AllOnes)
1321 return false;
1322 CC = N->getOperand(0);
1323 if (CC.getValueType() != MVT::i1)
1324 return false;
1325 SDLoc dl(N);
1326 EVT VT = N->getValueType(0);
1327 OtherOp = DAG.getConstant(1, dl, VT);
1328 Invert = true;
1329 return true;
1330 }
1331 case ISD::SIGN_EXTEND: {
1332 CC = N->getOperand(0);
1333 if (CC.getValueType() != MVT::i1)
1334 return false;
1335 SDLoc dl(N);
1336 EVT VT = N->getValueType(0);
1337 Invert = !AllOnes;
1338 if (AllOnes)
1339 // When looking for an AllOnes constant, N is an sext, and the 'other'
1340 // value is 0.
1341 OtherOp = DAG.getConstant(0, dl, VT);
1342 else
1343 OtherOp = DAG.getAllOnesConstant(dl, VT);
1344 return true;
1345 }
1346 }
1347}
1348
1349// Combine a constant select operand into its use:
1350//
1351// (add (select cc, 0, c), x) -> (select cc, x, (add, x, c))
1352// (sub x, (select cc, 0, c)) -> (select cc, x, (sub, x, c))
1353// (and (select cc, -1, c), x) -> (select cc, x, (and, x, c)) [AllOnes=1]
1354// (or (select cc, 0, c), x) -> (select cc, x, (or, x, c))
1355// (xor (select cc, 0, c), x) -> (select cc, x, (xor, x, c))
1356//
1357// The transform is rejected if the select doesn't have a constant operand that
1358// is null, or all ones when AllOnes is set.
1359//
1360// Also recognize sext/zext from i1:
1361//
1362// (add (zext cc), x) -> (select cc (add x, 1), x)
1363// (add (sext cc), x) -> (select cc (add x, -1), x)
1364//
1365// These transformations eventually create predicated instructions.
1368 bool AllOnes) {
1369 SelectionDAG &DAG = DCI.DAG;
1370 EVT VT = N->getValueType(0);
1371 SDValue NonConstantVal;
1372 SDValue CCOp;
1373 bool SwapSelectOps;
1374 if (!isConditionalZeroOrAllOnes(Slct.getNode(), AllOnes, CCOp, SwapSelectOps,
1375 NonConstantVal, DAG))
1376 return SDValue();
1377
1378 // Slct is now know to be the desired identity constant when CC is true.
1379 SDValue TrueVal = OtherOp;
1380 SDValue FalseVal =
1381 DAG.getNode(N->getOpcode(), SDLoc(N), VT, OtherOp, NonConstantVal);
1382 // Unless SwapSelectOps says CC should be false.
1383 if (SwapSelectOps)
1384 std::swap(TrueVal, FalseVal);
1385
1386 return DAG.getNode(ISD::SELECT, SDLoc(N), VT, CCOp, TrueVal, FalseVal);
1387}
1388
1389// Attempt combineSelectAndUse on each operand of a commutative operator N.
1390static SDValue
1392 bool AllOnes) {
1393 SDValue N0 = N->getOperand(0);
1394 SDValue N1 = N->getOperand(1);
1395 if (N0.getNode()->hasOneUse())
1396 if (SDValue Result = combineSelectAndUse(N, N0, N1, DCI, AllOnes))
1397 return Result;
1398 if (N1.getNode()->hasOneUse())
1399 if (SDValue Result = combineSelectAndUse(N, N1, N0, DCI, AllOnes))
1400 return Result;
1401 return SDValue();
1402}
1403
1404// PerformSUBCombine - Target-specific dag combine xforms for ISD::SUB.
1407 SDValue N0 = N->getOperand(0);
1408 SDValue N1 = N->getOperand(1);
1409
1410 // fold (sub x, (select cc, 0, c)) -> (select cc, x, (sub, x, c))
1411 if (N1.getNode()->hasOneUse())
1412 if (SDValue Result = combineSelectAndUse(N, N1, N0, DCI, /*AllOnes=*/false))
1413 return Result;
1414
1415 return SDValue();
1416}
1417
1419 DAGCombinerInfo &DCI) const {
1420 switch (N->getOpcode()) {
1421 default:
1422 break;
1423 case ISD::ADD:
1424 case ISD::OR:
1425 case ISD::XOR:
1426 return combineSelectAndUseCommutative(N, DCI, /*AllOnes=*/false);
1427 case ISD::AND:
1428 return combineSelectAndUseCommutative(N, DCI, /*AllOnes=*/true);
1429 case ISD::SUB:
1430 return PerformSUBCombine(N, DCI);
1431 }
1432
1433 return SDValue();
1434}
1435
1437 const SDValue Op, KnownBits &Known, const APInt &DemandedElts,
1438 const SelectionDAG &DAG, unsigned Depth) const {
1439 unsigned BitWidth = Known.getBitWidth();
1440 switch (Op.getOpcode()) {
1441 default:
1442 break;
1443 case LanaiISD::SETCC:
1445 Known.Zero.setBits(1, BitWidth);
1446 break;
1447 case LanaiISD::SELECT_CC:
1448 KnownBits Known2;
1449 Known = DAG.computeKnownBits(Op->getOperand(0), Depth + 1);
1450 Known2 = DAG.computeKnownBits(Op->getOperand(1), Depth + 1);
1451 Known = Known.intersectWith(Known2);
1452 break;
1453 }
1454}
return SDValue()
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements a class to represent arbitrary precision integral constant values and operations...
static bool isZeroOrAllOnes(SDValue N, bool AllOnes)
static SDValue PerformSUBCombine(SDNode *N, TargetLowering::DAGCombinerInfo &DCI, const ARMSubtarget *Subtarget)
PerformSUBCombine - Target-specific dag combine xforms for ISD::SUB.
static SDValue combineSelectAndUseCommutative(SDNode *N, bool AllOnes, TargetLowering::DAGCombinerInfo &DCI)
static bool isConditionalZeroOrAllOnes(SDNode *N, bool AllOnes, SDValue &CC, bool &Invert, SDValue &OtherOp, SelectionDAG &DAG)
static SDValue combineSelectAndUse(SDNode *N, SDValue Slct, SDValue OtherOp, TargetLowering::DAGCombinerInfo &DCI, bool AllOnes=false)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
#define RegName(no)
static LPCC::CondCode IntCondCCodeToICC(SDValue CC, const SDLoc &DL, SDValue &RHS, SelectionDAG &DAG)
static cl::opt< int > LanaiLowerConstantMulThreshold("lanai-constant-mul-threshold", cl::Hidden, cl::desc("Maximum number of instruction to generate when lowering constant " "multiplication instead of calling library function [default=14]"), cl::init(14))
static bool CC_Lanai32_VarArg(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, Type *OrigTy, CCState &State)
#define I(x, y, z)
Definition MD5.cpp:57
#define G(x, y, z)
Definition MD5.cpp:55
Register Reg
Promote Memory to Register
Definition Mem2Reg.cpp:110
static CodeModel::Model getCodeModel(const PPCSubtarget &S, const TargetMachine &TM, const MachineOperand &MO)
static constexpr MCPhysReg SPReg
const SmallVectorImpl< MachineOperand > & Cond
This file defines the SmallVector class.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
#define LLVM_DEBUG(...)
Definition Debug.h:119
Value * RHS
Class for arbitrary precision integers.
Definition APInt.h:78
The address of a basic block.
Definition Constants.h:1088
CCState - This class holds information needed while lowering arguments and return values.
LLVM_ABI bool CheckReturn(const SmallVectorImpl< ISD::OutputArg > &Outs, CCAssignFn Fn)
CheckReturn - Analyze the return values of a function, returning true if the return can be performed ...
CCValAssign - Represent assignment of one arg/retval to a location.
Register getLocReg() const
LocInfo getLocInfo() const
static CCValAssign getMem(unsigned ValNo, MVT ValVT, int64_t Offset, MVT LocVT, LocInfo HTP, bool IsCustom=false)
int64_t getLocMemOffset() const
This is an important base class in LLVM.
Definition Constant.h:43
bool hasStructRetAttr() const
Determine if the function returns a structure through first or second pointer argument.
Definition Function.h:669
LLVM_ABI const GlobalObject * getAliaseeObject() const
Definition Globals.cpp:521
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
const LanaiRegisterInfo * getRegisterInfo() const override
SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const
SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const
SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const
SDValue LowerSRL_PARTS(SDValue Op, SelectionDAG &DAG) const
SDValue LowerMUL(SDValue Op, SelectionDAG &DAG) const
void computeKnownBitsForTargetNode(const SDValue Op, KnownBits &Known, const APInt &DemandedElts, const SelectionDAG &DAG, unsigned Depth=0) const override
Determine which of the bits specified in Mask are known to be either zero or one and return them in t...
SDValue LowerSHL_PARTS(SDValue Op, SelectionDAG &DAG) const
SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG) const
LanaiTargetLowering(const TargetMachine &TM, const LanaiSubtarget &STI)
SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const
SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const
Register getRegisterByName(const char *RegName, LLT VT, const MachineFunction &MF) const override
Return the register ID of the name passed in.
SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const
SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const
SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const
SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const
bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg, const SmallVectorImpl< ISD::OutputArg > &Outs, LLVMContext &Context, const Type *RetTy) const override
This hook should be implemented to check whether the return values described by the Outs array can fi...
ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &Info, const char *Constraint) const override
Examine constraint string and operand type and determine a weight value.
void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const override
Lower the specified operand into the Ops vector.
SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const
SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override
This method will be invoked for all target nodes and for any target-independent nodes that the target...
std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const override
Given a physical register constraint (e.g.
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
This callback is invoked for operations that are unsupported by the target, which are registered to u...
bool isConstantInSmallSection(const DataLayout &DL, const Constant *CN) const
Return true if this constant should be placed into small data section.
Machine Value Type.
SimpleValueType SimpleTy
static auto integer_valuetypes()
TypeSize getSizeInBits() const
Returns the size of the specified MVT in bits.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
LLVM_ABI int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects.
LLVM_ABI int CreateStackObject(uint64_t Size, Align Alignment, bool isSpillSlot, const AllocaInst *Alloca=nullptr, uint8_t ID=0)
Create a new statically sized stack object, returning a nonnegative identifier to represent it.
void setFrameAddressIsTaken(bool T)
void setReturnAddressIsTaken(bool s)
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Register addLiveIn(MCRegister PReg, const TargetRegisterClass *RC)
addLiveIn - Add the specified physical register as a live-in value and create a corresponding virtual...
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
void addLiveIn(MCRegister Reg, Register vreg=Register())
addLiveIn - Add the specified register as a live-in.
Wrapper class representing virtual and physical registers.
Definition Register.h:20
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
bool hasOneUse() const
Return true if there is exactly one use of this node.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation.
SDNode * getNode() const
get the SDNode which holds the desired result
SDValue getValue(unsigned R) const
EVT getValueType() const
Return the ValueType of the referenced return value.
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, Register Reg, SDValue N)
LLVM_ABI SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
LLVM_ABI SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
LLVM_ABI SDValue getAllOnesConstant(const SDLoc &DL, EVT VT, bool IsTarget=false, bool IsOpaque=false)
LLVM_ABI SDValue getRegister(Register Reg, EVT VT)
LLVM_ABI SDValue getLoad(EVT VT, const SDLoc &dl, SDValue Chain, SDValue Ptr, MachinePointerInfo PtrInfo, MaybeAlign Alignment=MaybeAlign(), MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr)
Loads are not normal binary operators: their result type is not determined by their operands,...
SDValue getSetCC(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, ISD::CondCode Cond, SDValue Chain=SDValue(), bool IsSignaling=false, SDNodeFlags Flags={})
Helper function to make it easier to build SetCC's if you just have an ISD::CondCode instead of an SD...
LLVM_ABI SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align DstAlign, Align SrcAlign, bool isVol, bool AlwaysInline, const CallInst *CI, std::optional< bool > OverrideTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), BatchAAResults *BatchAA=nullptr)
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
SDValue getCALLSEQ_END(SDValue Chain, SDValue Op1, SDValue Op2, SDValue InGlue, const SDLoc &DL)
Return a new CALLSEQ_END node, which always must have a glue result (to ensure it's not CSE'd).
SDValue getCopyFromReg(SDValue Chain, const SDLoc &dl, Register Reg, EVT VT)
SDValue getSelect(const SDLoc &DL, EVT VT, SDValue Cond, SDValue LHS, SDValue RHS, SDNodeFlags Flags=SDNodeFlags())
Helper function to make it easier to build Select's if you just have operands and don't want to check...
const DataLayout & getDataLayout() const
LLVM_ABI SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
LLVM_ABI SDValue getStore(SDValue Chain, const SDLoc &dl, SDValue Val, SDValue Ptr, MachinePointerInfo PtrInfo, Align Alignment, MachineMemOperand::Flags MMOFlags=MachineMemOperand::MONone, const AAMDNodes &AAInfo=AAMDNodes())
Helper function to build ISD::STORE nodes.
SDValue getCALLSEQ_START(SDValue Chain, uint64_t InSize, uint64_t OutSize, const SDLoc &DL)
Return a new CALLSEQ_START node, that starts new call frame, in which InSize bytes are set up inside ...
LLVM_ABI SDValue getBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, bool isTarget=false, unsigned TargetFlags=0)
LLVM_ABI SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
LLVM_ABI SDValue getValueType(EVT)
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
SDValue getTargetConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isOpaque=false)
MachineFunction & getMachineFunction() const
LLVM_ABI SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
LLVM_ABI KnownBits computeKnownBits(SDValue Op, unsigned Depth=0) const
Determine which bits of Op are known to be either zero or one and return them in Known.
LLVM_ABI SDValue getRegisterMask(const uint32_t *RegMask)
LLVMContext * getContext() const
LLVM_ABI SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)
SDValue getTargetConstantPool(const Constant *C, EVT VT, MaybeAlign Align=std::nullopt, int Offset=0, unsigned TargetFlags=0)
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
constexpr size_t size() const
Get the string size.
Definition StringRef.h:144
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
void setOperationAction(unsigned Op, MVT VT, LegalizeAction Action)
Indicate that the specified operation does not work with the specified type and indicate what to do a...
unsigned MaxStoresPerMemcpyOptSize
Likewise for functions with the OptSize attribute.
virtual const TargetRegisterClass * getRegClassFor(MVT VT, bool isDivergent=false) const
Return the register class that should be used for the specified value type.
const TargetMachine & getTargetMachine() const
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
Register getStackPointerRegisterToSaveRestore() const
If a physical register, this specifies the register that llvm.savestack/llvm.restorestack should save...
void setMinFunctionAlignment(Align Alignment)
Set the target's minimum function alignment.
unsigned MaxStoresPerMemsetOptSize
Likewise for functions with the OptSize attribute.
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
unsigned MaxStoresPerMemmove
Specify maximum number of store instructions per memmove call.
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
unsigned MaxStoresPerMemmoveOptSize
Likewise for functions with the OptSize attribute.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
virtual MVT getPointerTy(const DataLayout &DL, uint32_t AS=0) const
Return the pointer type for the given address space, defaults to the pointer type from the data layou...
void setPrefFunctionAlignment(Align Alignment)
Set the target's preferred function alignment.
unsigned MaxStoresPerMemset
Specify maximum number of store instructions per memset call.
void setMinimumJumpTableEntries(unsigned Val)
Indicate the minimum number of blocks to generate jump tables.
void setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
void setTargetDAGCombine(ArrayRef< ISD::NodeType > NTs)
Targets should invoke this method for each target independent node that they want to provide a custom...
void setLoadExtAction(unsigned ExtType, MVT ValVT, MVT MemVT, LegalizeAction Action)
Indicate that the specified load with extension does not work with the specified type and indicate wh...
unsigned MaxStoresPerMemcpy
Specify maximum number of store instructions per memcpy call.
void setJumpIsExpensive(bool isExpensive=true)
Tells the code generator not to expand logic operations on comparison predicates into separate sequen...
virtual ConstraintWeight getSingleConstraintMatchWeight(AsmOperandInfo &info, const char *constraint) const
Examine constraint string and operand type and determine a weight value.
virtual std::pair< unsigned, const TargetRegisterClass * > getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, StringRef Constraint, MVT VT) const
Given a physical register constraint (e.g.
TargetLowering(const TargetLowering &)=delete
virtual void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, std::vector< SDValue > &Ops, SelectionDAG &DAG) const
Lower the specified operand into the Ops vector.
Primary interface to the complete machine description for the target machine.
virtual TargetLoweringObjectFile * getObjFileLowering() const
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
LLVM Value Representation.
Definition Value.h:75
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
@ Fast
Attempts to make calls as fast as possible (e.g.
Definition CallingConv.h:41
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
@ SETCC
SetCC operator - This evaluates to a true value iff the condition is true.
Definition ISDOpcodes.h:829
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
Definition ISDOpcodes.h:275
@ BSWAP
Byte Swap and Counting operators.
Definition ISDOpcodes.h:789
@ VAEND
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE.
@ ADD
Simple integer binary arithmetic operators.
Definition ISDOpcodes.h:264
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
Definition ISDOpcodes.h:863
@ GlobalAddress
Definition ISDOpcodes.h:88
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
Definition ISDOpcodes.h:280
@ SIGN_EXTEND
Conversion operators.
Definition ISDOpcodes.h:854
@ BR_CC
BR_CC - Conditional branch.
@ BR_JT
BR_JT - Jumptable branch.
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
Definition ISDOpcodes.h:806
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
Definition ISDOpcodes.h:706
@ SHL
Shift and rotation operations.
Definition ISDOpcodes.h:771
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
Definition ISDOpcodes.h:860
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
Definition ISDOpcodes.h:821
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
Definition ISDOpcodes.h:898
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
Definition ISDOpcodes.h:110
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition ISDOpcodes.h:741
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
Definition ISDOpcodes.h:53
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
Definition ISDOpcodes.h:866
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
@ BRCOND
BRCOND - Conditional branch.
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
Definition ISDOpcodes.h:843
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
Definition ISDOpcodes.h:62
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:573
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Definition MathExtras.h:165
LLVM_ABI bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
@ Known
Known to have no common set bits.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
Definition MathExtras.h:189
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
@ Sub
Subtraction of integers.
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
LLVM_ABI bool isAllOnesConstant(SDValue V)
Returns true if V is an integer constant with all bits set.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:862
#define N
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
Extended Value Type.
Definition ValueTypes.h:35
TypeSize getSizeInBits() const
Return the size of the specified value type in bits.
Definition ValueTypes.h:396
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition ValueTypes.h:339
This class contains a discriminated union of information about pointers in memory operands,...
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
This contains information for each constraint that we are lowering.
This structure contains all information that is necessary for lowering calls.
SmallVector< ISD::InputArg, 32 > Ins
SmallVector< ISD::OutputArg, 32 > Outs