LLVM 20.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) {
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 // Use fast calling convention for library functions.
154 for (int I = 0; I < RTLIB::UNKNOWN_LIBCALL; ++I) {
156 }
157
158 MaxStoresPerMemset = 16; // For @llvm.memset -> sequence of stores
160 MaxStoresPerMemcpy = 16; // For @llvm.memcpy -> sequence of stores
162 MaxStoresPerMemmove = 16; // For @llvm.memmove -> sequence of stores
164
165 // Booleans always contain 0 or 1.
167
169}
170
172 SelectionDAG &DAG) const {
173 switch (Op.getOpcode()) {
174 case ISD::MUL:
175 return LowerMUL(Op, DAG);
176 case ISD::BR_CC:
177 return LowerBR_CC(Op, DAG);
179 return LowerConstantPool(Op, DAG);
181 return LowerGlobalAddress(Op, DAG);
183 return LowerBlockAddress(Op, DAG);
184 case ISD::JumpTable:
185 return LowerJumpTable(Op, DAG);
186 case ISD::SELECT_CC:
187 return LowerSELECT_CC(Op, DAG);
188 case ISD::SETCC:
189 return LowerSETCC(Op, DAG);
190 case ISD::SHL_PARTS:
191 return LowerSHL_PARTS(Op, DAG);
192 case ISD::SRL_PARTS:
193 return LowerSRL_PARTS(Op, DAG);
194 case ISD::VASTART:
195 return LowerVASTART(Op, DAG);
197 return LowerDYNAMIC_STACKALLOC(Op, DAG);
198 case ISD::RETURNADDR:
199 return LowerRETURNADDR(Op, DAG);
200 case ISD::FRAMEADDR:
201 return LowerFRAMEADDR(Op, DAG);
202 default:
203 llvm_unreachable("unimplemented operand");
204 }
205}
206
207//===----------------------------------------------------------------------===//
208// Lanai Inline Assembly Support
209//===----------------------------------------------------------------------===//
210
212 const char *RegName, LLT /*VT*/,
213 const MachineFunction & /*MF*/) const {
214 // Only unallocatable registers should be matched here.
216 .Case("pc", Lanai::PC)
217 .Case("sp", Lanai::SP)
218 .Case("fp", Lanai::FP)
219 .Case("rr1", Lanai::RR1)
220 .Case("r10", Lanai::R10)
221 .Case("rr2", Lanai::RR2)
222 .Case("r11", Lanai::R11)
223 .Case("rca", Lanai::RCA)
224 .Default(0);
225
226 if (Reg)
227 return Reg;
228 report_fatal_error("Invalid register name global variable");
229}
230
231std::pair<unsigned, const TargetRegisterClass *>
233 StringRef Constraint,
234 MVT VT) const {
235 if (Constraint.size() == 1)
236 // GCC Constraint Letters
237 switch (Constraint[0]) {
238 case 'r': // GENERAL_REGS
239 return std::make_pair(0U, &Lanai::GPRRegClass);
240 default:
241 break;
242 }
243
245}
246
247// Examine constraint type and operand type and determine a weight value.
248// This object must already have been set up with the operand type
249// and the current alternative constraint selected.
252 AsmOperandInfo &Info, const char *Constraint) const {
254 Value *CallOperandVal = Info.CallOperandVal;
255 // If we don't have a value, we can't do a match,
256 // but allow it at the lowest weight.
257 if (CallOperandVal == nullptr)
258 return CW_Default;
259 // Look at the constraint type.
260 switch (*Constraint) {
261 case 'I': // signed 16 bit immediate
262 case 'J': // integer zero
263 case 'K': // unsigned 16 bit immediate
264 case 'L': // immediate in the range 0 to 31
265 case 'M': // signed 32 bit immediate where lower 16 bits are 0
266 case 'N': // signed 26 bit immediate
267 case 'O': // integer zero
268 if (isa<ConstantInt>(CallOperandVal))
269 Weight = CW_Constant;
270 break;
271 default:
273 break;
274 }
275 return Weight;
276}
277
278// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
279// vector. If it is invalid, don't add anything to Ops.
281 SDValue Op, StringRef Constraint, std::vector<SDValue> &Ops,
282 SelectionDAG &DAG) const {
283 SDValue Result;
284
285 // Only support length 1 constraints for now.
286 if (Constraint.size() > 1)
287 return;
288
289 char ConstraintLetter = Constraint[0];
290 switch (ConstraintLetter) {
291 case 'I': // Signed 16 bit constant
292 // If this fails, the parent routine will give an error
293 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
294 if (isInt<16>(C->getSExtValue())) {
295 Result = DAG.getTargetConstant(C->getSExtValue(), SDLoc(C),
296 Op.getValueType());
297 break;
298 }
299 }
300 return;
301 case 'J': // integer zero
302 case 'O':
303 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
304 if (C->getZExtValue() == 0) {
305 Result = DAG.getTargetConstant(0, SDLoc(C), Op.getValueType());
306 break;
307 }
308 }
309 return;
310 case 'K': // unsigned 16 bit immediate
311 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
312 if (isUInt<16>(C->getZExtValue())) {
313 Result = DAG.getTargetConstant(C->getSExtValue(), SDLoc(C),
314 Op.getValueType());
315 break;
316 }
317 }
318 return;
319 case 'L': // immediate in the range 0 to 31
320 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
321 if (C->getZExtValue() <= 31) {
322 Result = DAG.getTargetConstant(C->getZExtValue(), SDLoc(C),
323 Op.getValueType());
324 break;
325 }
326 }
327 return;
328 case 'M': // signed 32 bit immediate where lower 16 bits are 0
329 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
330 int64_t Val = C->getSExtValue();
331 if ((isInt<32>(Val)) && ((Val & 0xffff) == 0)) {
332 Result = DAG.getTargetConstant(Val, SDLoc(C), Op.getValueType());
333 break;
334 }
335 }
336 return;
337 case 'N': // signed 26 bit immediate
338 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
339 int64_t Val = C->getSExtValue();
340 if ((Val >= -33554432) && (Val <= 33554431)) {
341 Result = DAG.getTargetConstant(Val, SDLoc(C), Op.getValueType());
342 break;
343 }
344 }
345 return;
346 default:
347 break; // This will fall through to the generic implementation
348 }
349
350 if (Result.getNode()) {
351 Ops.push_back(Result);
352 return;
353 }
354
356}
357
358//===----------------------------------------------------------------------===//
359// Calling Convention Implementation
360//===----------------------------------------------------------------------===//
361
362#include "LanaiGenCallingConv.inc"
363
364static unsigned NumFixedArgs;
365static bool CC_Lanai32_VarArg(unsigned ValNo, MVT ValVT, MVT LocVT,
366 CCValAssign::LocInfo LocInfo,
367 ISD::ArgFlagsTy ArgFlags, CCState &State) {
368 // Handle fixed arguments with default CC.
369 // Note: Both the default and fast CC handle VarArg the same and hence the
370 // calling convention of the function is not considered here.
371 if (ValNo < NumFixedArgs) {
372 return CC_Lanai32(ValNo, ValVT, LocVT, LocInfo, ArgFlags, State);
373 }
374
375 // Promote i8/i16 args to i32
376 if (LocVT == MVT::i8 || LocVT == MVT::i16) {
377 LocVT = MVT::i32;
378 if (ArgFlags.isSExt())
379 LocInfo = CCValAssign::SExt;
380 else if (ArgFlags.isZExt())
381 LocInfo = CCValAssign::ZExt;
382 else
383 LocInfo = CCValAssign::AExt;
384 }
385
386 // VarArgs get passed on stack
387 unsigned Offset = State.AllocateStack(4, Align(4));
388 State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo));
389 return false;
390}
391
392SDValue LanaiTargetLowering::LowerFormalArguments(
393 SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
394 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
395 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
396 switch (CallConv) {
397 case CallingConv::C:
399 return LowerCCCArguments(Chain, CallConv, IsVarArg, Ins, DL, DAG, InVals);
400 default:
401 report_fatal_error("Unsupported calling convention");
402 }
403}
404
405SDValue LanaiTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
406 SmallVectorImpl<SDValue> &InVals) const {
407 SelectionDAG &DAG = CLI.DAG;
408 SDLoc &DL = CLI.DL;
410 SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
412 SDValue Chain = CLI.Chain;
413 SDValue Callee = CLI.Callee;
414 bool &IsTailCall = CLI.IsTailCall;
415 CallingConv::ID CallConv = CLI.CallConv;
416 bool IsVarArg = CLI.IsVarArg;
417
418 // Lanai target does not yet support tail call optimization.
419 IsTailCall = false;
420
421 switch (CallConv) {
423 case CallingConv::C:
424 return LowerCCCCallTo(Chain, Callee, CallConv, IsVarArg, IsTailCall, Outs,
425 OutVals, Ins, DL, DAG, InVals);
426 default:
427 report_fatal_error("Unsupported calling convention");
428 }
429}
430
431// LowerCCCArguments - transform physical registers into virtual registers and
432// generate load operations for arguments places on the stack.
433SDValue LanaiTargetLowering::LowerCCCArguments(
434 SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
435 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
436 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
438 MachineFrameInfo &MFI = MF.getFrameInfo();
441
442 // Assign locations to all of the incoming arguments.
444 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs,
445 *DAG.getContext());
446 if (CallConv == CallingConv::Fast) {
447 CCInfo.AnalyzeFormalArguments(Ins, CC_Lanai32_Fast);
448 } else {
449 CCInfo.AnalyzeFormalArguments(Ins, CC_Lanai32);
450 }
451
452 for (const CCValAssign &VA : ArgLocs) {
453 if (VA.isRegLoc()) {
454 // Arguments passed in registers
455 EVT RegVT = VA.getLocVT();
456 switch (RegVT.getSimpleVT().SimpleTy) {
457 case MVT::i32: {
458 Register VReg = RegInfo.createVirtualRegister(&Lanai::GPRRegClass);
459 RegInfo.addLiveIn(VA.getLocReg(), VReg);
460 SDValue ArgValue = DAG.getCopyFromReg(Chain, DL, VReg, RegVT);
461
462 // If this is an 8/16-bit value, it is really passed promoted to 32
463 // bits. Insert an assert[sz]ext to capture this, then truncate to the
464 // right size.
465 if (VA.getLocInfo() == CCValAssign::SExt)
466 ArgValue = DAG.getNode(ISD::AssertSext, DL, RegVT, ArgValue,
467 DAG.getValueType(VA.getValVT()));
468 else if (VA.getLocInfo() == CCValAssign::ZExt)
469 ArgValue = DAG.getNode(ISD::AssertZext, DL, RegVT, ArgValue,
470 DAG.getValueType(VA.getValVT()));
471
472 if (VA.getLocInfo() != CCValAssign::Full)
473 ArgValue = DAG.getNode(ISD::TRUNCATE, DL, VA.getValVT(), ArgValue);
474
475 InVals.push_back(ArgValue);
476 break;
477 }
478 default:
479 LLVM_DEBUG(dbgs() << "LowerFormalArguments Unhandled argument type: "
480 << RegVT << "\n");
481 llvm_unreachable("unhandled argument type");
482 }
483 } else {
484 // Only arguments passed on the stack should make it here.
485 assert(VA.isMemLoc());
486 // Load the argument to a virtual register
487 unsigned ObjSize = VA.getLocVT().getSizeInBits() / 8;
488 // Check that the argument fits in stack slot
489 if (ObjSize > 4) {
490 errs() << "LowerFormalArguments Unhandled argument type: "
491 << VA.getLocVT() << "\n";
492 }
493 // Create the frame index object for this incoming parameter...
494 int FI = MFI.CreateFixedObject(ObjSize, VA.getLocMemOffset(), true);
495
496 // Create the SelectionDAG nodes corresponding to a load
497 // from this parameter
498 SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);
499 InVals.push_back(DAG.getLoad(
500 VA.getLocVT(), DL, Chain, FIN,
502 }
503 }
504
505 // The Lanai ABI for returning structs by value requires that we copy
506 // the sret argument into rv for the return. Save the argument into
507 // a virtual register so that we can access it from the return points.
508 if (MF.getFunction().hasStructRetAttr()) {
509 Register Reg = LanaiMFI->getSRetReturnReg();
510 if (!Reg) {
512 LanaiMFI->setSRetReturnReg(Reg);
513 }
514 SDValue Copy = DAG.getCopyToReg(DAG.getEntryNode(), DL, Reg, InVals[0]);
515 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Copy, Chain);
516 }
517
518 if (IsVarArg) {
519 // Record the frame index of the first variable argument
520 // which is a value necessary to VASTART.
521 int FI = MFI.CreateFixedObject(4, CCInfo.getStackSize(), true);
522 LanaiMFI->setVarArgsFrameIndex(FI);
523 }
524
525 return Chain;
526}
527
529 CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,
530 const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context) const {
532 CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
533
534 return CCInfo.CheckReturn(Outs, RetCC_Lanai32);
535}
536
538LanaiTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
539 bool IsVarArg,
541 const SmallVectorImpl<SDValue> &OutVals,
542 const SDLoc &DL, SelectionDAG &DAG) const {
543 // CCValAssign - represent the assignment of the return value to a location
545
546 // CCState - Info about the registers and stack slot.
547 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs,
548 *DAG.getContext());
549
550 // Analize return values.
551 CCInfo.AnalyzeReturn(Outs, RetCC_Lanai32);
552
553 SDValue Glue;
554 SmallVector<SDValue, 4> RetOps(1, Chain);
555
556 // Copy the result values into the output registers.
557 for (unsigned i = 0; i != RVLocs.size(); ++i) {
558 CCValAssign &VA = RVLocs[i];
559 assert(VA.isRegLoc() && "Can only return in registers!");
560
561 Chain = DAG.getCopyToReg(Chain, DL, VA.getLocReg(), OutVals[i], Glue);
562
563 // Guarantee that all emitted copies are stuck together with flags.
564 Glue = Chain.getValue(1);
565 RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
566 }
567
568 // The Lanai ABI for returning structs by value requires that we copy
569 // the sret argument into rv for the return. We saved the argument into
570 // a virtual register in the entry block, so now we copy the value out
571 // and into rv.
575 Register Reg = LanaiMFI->getSRetReturnReg();
576 assert(Reg &&
577 "SRetReturnReg should have been set in LowerFormalArguments().");
578 SDValue Val =
579 DAG.getCopyFromReg(Chain, DL, Reg, getPointerTy(DAG.getDataLayout()));
580
581 Chain = DAG.getCopyToReg(Chain, DL, Lanai::RV, Val, Glue);
582 Glue = Chain.getValue(1);
583 RetOps.push_back(
584 DAG.getRegister(Lanai::RV, getPointerTy(DAG.getDataLayout())));
585 }
586
587 RetOps[0] = Chain; // Update chain
588
589 unsigned Opc = LanaiISD::RET_GLUE;
590 if (Glue.getNode())
591 RetOps.push_back(Glue);
592
593 // Return Void
594 return DAG.getNode(Opc, DL, MVT::Other,
595 ArrayRef<SDValue>(&RetOps[0], RetOps.size()));
596}
597
598// LowerCCCCallTo - functions arguments are copied from virtual regs to
599// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted.
600SDValue LanaiTargetLowering::LowerCCCCallTo(
601 SDValue Chain, SDValue Callee, CallingConv::ID CallConv, bool IsVarArg,
602 bool /*IsTailCall*/, const SmallVectorImpl<ISD::OutputArg> &Outs,
603 const SmallVectorImpl<SDValue> &OutVals,
604 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
605 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
606 // Analyze operands of the call, assigning locations to each operand.
608 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs,
609 *DAG.getContext());
610 GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee);
612
613 NumFixedArgs = 0;
614 if (IsVarArg && G) {
615 const Function *CalleeFn = dyn_cast<Function>(G->getGlobal());
616 if (CalleeFn)
618 }
619 if (NumFixedArgs)
620 CCInfo.AnalyzeCallOperands(Outs, CC_Lanai32_VarArg);
621 else {
622 if (CallConv == CallingConv::Fast)
623 CCInfo.AnalyzeCallOperands(Outs, CC_Lanai32_Fast);
624 else
625 CCInfo.AnalyzeCallOperands(Outs, CC_Lanai32);
626 }
627
628 // Get a count of how many bytes are to be pushed on the stack.
629 unsigned NumBytes = CCInfo.getStackSize();
630
631 // Create local copies for byval args.
632 SmallVector<SDValue, 8> ByValArgs;
633 for (unsigned I = 0, E = Outs.size(); I != E; ++I) {
634 ISD::ArgFlagsTy Flags = Outs[I].Flags;
635 if (!Flags.isByVal())
636 continue;
637
638 SDValue Arg = OutVals[I];
639 unsigned Size = Flags.getByValSize();
640 Align Alignment = Flags.getNonZeroByValAlign();
641
642 int FI = MFI.CreateStackObject(Size, Alignment, false);
643 SDValue FIPtr = DAG.getFrameIndex(FI, getPointerTy(DAG.getDataLayout()));
644 SDValue SizeNode = DAG.getConstant(Size, DL, MVT::i32);
645
646 Chain = DAG.getMemcpy(Chain, DL, FIPtr, Arg, SizeNode, Alignment,
647 /*IsVolatile=*/false,
648 /*AlwaysInline=*/false,
649 /*CI=*/nullptr, std::nullopt, MachinePointerInfo(),
651 ByValArgs.push_back(FIPtr);
652 }
653
654 Chain = DAG.getCALLSEQ_START(Chain, NumBytes, 0, DL);
655
657 SmallVector<SDValue, 12> MemOpChains;
659
660 // Walk the register/memloc assignments, inserting copies/loads.
661 for (unsigned I = 0, J = 0, E = ArgLocs.size(); I != E; ++I) {
662 CCValAssign &VA = ArgLocs[I];
663 SDValue Arg = OutVals[I];
664 ISD::ArgFlagsTy Flags = Outs[I].Flags;
665
666 // Promote the value if needed.
667 switch (VA.getLocInfo()) {
669 break;
671 Arg = DAG.getNode(ISD::SIGN_EXTEND, DL, VA.getLocVT(), Arg);
672 break;
674 Arg = DAG.getNode(ISD::ZERO_EXTEND, DL, VA.getLocVT(), Arg);
675 break;
677 Arg = DAG.getNode(ISD::ANY_EXTEND, DL, VA.getLocVT(), Arg);
678 break;
679 default:
680 llvm_unreachable("Unknown loc info!");
681 }
682
683 // Use local copy if it is a byval arg.
684 if (Flags.isByVal())
685 Arg = ByValArgs[J++];
686
687 // Arguments that can be passed on register must be kept at RegsToPass
688 // vector
689 if (VA.isRegLoc()) {
690 RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
691 } else {
692 assert(VA.isMemLoc());
693
694 if (StackPtr.getNode() == nullptr)
695 StackPtr = DAG.getCopyFromReg(Chain, DL, Lanai::SP,
697
698 SDValue PtrOff =
699 DAG.getNode(ISD::ADD, DL, getPointerTy(DAG.getDataLayout()), StackPtr,
701
702 MemOpChains.push_back(
703 DAG.getStore(Chain, DL, Arg, PtrOff, MachinePointerInfo()));
704 }
705 }
706
707 // Transform all store nodes into one single node because all store nodes are
708 // independent of each other.
709 if (!MemOpChains.empty())
710 Chain = DAG.getNode(ISD::TokenFactor, DL, MVT::Other,
711 ArrayRef<SDValue>(&MemOpChains[0], MemOpChains.size()));
712
713 SDValue InGlue;
714
715 // Build a sequence of copy-to-reg nodes chained together with token chain and
716 // flag operands which copy the outgoing args into registers. The InGlue in
717 // necessary since all emitted instructions must be stuck together.
718 for (unsigned I = 0, E = RegsToPass.size(); I != E; ++I) {
719 Chain = DAG.getCopyToReg(Chain, DL, RegsToPass[I].first,
720 RegsToPass[I].second, InGlue);
721 InGlue = Chain.getValue(1);
722 }
723
724 // If the callee is a GlobalAddress node (quite common, every direct call is)
725 // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
726 // Likewise ExternalSymbol -> TargetExternalSymbol.
728 if (G) {
730 G->getGlobal(), DL, getPointerTy(DAG.getDataLayout()), 0, OpFlag);
731 } else if (ExternalSymbolSDNode *E = dyn_cast<ExternalSymbolSDNode>(Callee)) {
733 E->getSymbol(), getPointerTy(DAG.getDataLayout()), OpFlag);
734 }
735
736 // Returns a chain & a flag for retval copy to use.
737 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
739 Ops.push_back(Chain);
740 Ops.push_back(Callee);
741
742 // Add a register mask operand representing the call-preserved registers.
743 // TODO: Should return-twice functions be handled?
744 const uint32_t *Mask =
745 TRI->getCallPreservedMask(DAG.getMachineFunction(), CallConv);
746 assert(Mask && "Missing call preserved mask for calling convention");
747 Ops.push_back(DAG.getRegisterMask(Mask));
748
749 // Add argument registers to the end of the list so that they are
750 // known live into the call.
751 for (unsigned I = 0, E = RegsToPass.size(); I != E; ++I)
752 Ops.push_back(DAG.getRegister(RegsToPass[I].first,
753 RegsToPass[I].second.getValueType()));
754
755 if (InGlue.getNode())
756 Ops.push_back(InGlue);
757
758 Chain = DAG.getNode(LanaiISD::CALL, DL, NodeTys,
759 ArrayRef<SDValue>(&Ops[0], Ops.size()));
760 InGlue = Chain.getValue(1);
761
762 // Create the CALLSEQ_END node.
763 Chain = DAG.getCALLSEQ_END(Chain, NumBytes, 0, InGlue, DL);
764 InGlue = Chain.getValue(1);
765
766 // Handle result values, copying them out of physregs into vregs that we
767 // return.
768 return LowerCallResult(Chain, InGlue, CallConv, IsVarArg, Ins, DL, DAG,
769 InVals);
770}
771
772// LowerCallResult - Lower the result values of a call into the
773// appropriate copies out of appropriate physical registers.
774SDValue LanaiTargetLowering::LowerCallResult(
775 SDValue Chain, SDValue InGlue, CallingConv::ID CallConv, bool IsVarArg,
776 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &DL,
777 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
778 // Assign locations to each value returned by this call.
780 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs,
781 *DAG.getContext());
782
783 CCInfo.AnalyzeCallResult(Ins, RetCC_Lanai32);
784
785 // Copy all of the result registers out of their specified physreg.
786 for (unsigned I = 0; I != RVLocs.size(); ++I) {
787 Chain = DAG.getCopyFromReg(Chain, DL, RVLocs[I].getLocReg(),
788 RVLocs[I].getValVT(), InGlue)
789 .getValue(1);
790 InGlue = Chain.getValue(2);
791 InVals.push_back(Chain.getValue(0));
792 }
793
794 return Chain;
795}
796
797//===----------------------------------------------------------------------===//
798// Custom Lowerings
799//===----------------------------------------------------------------------===//
800
802 SDValue &RHS, SelectionDAG &DAG) {
803 ISD::CondCode SetCCOpcode = cast<CondCodeSDNode>(CC)->get();
804
805 // For integer, only the SETEQ, SETNE, SETLT, SETLE, SETGT, SETGE, SETULT,
806 // SETULE, SETUGT, and SETUGE opcodes are used (see CodeGen/ISDOpcodes.h)
807 // and Lanai only supports integer comparisons, so only provide definitions
808 // for them.
809 switch (SetCCOpcode) {
810 case ISD::SETEQ:
811 return LPCC::ICC_EQ;
812 case ISD::SETGT:
813 if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS))
814 if (RHSC->getZExtValue() == 0xFFFFFFFF) {
815 // X > -1 -> X >= 0 -> is_plus(X)
816 RHS = DAG.getConstant(0, DL, RHS.getValueType());
817 return LPCC::ICC_PL;
818 }
819 return LPCC::ICC_GT;
820 case ISD::SETUGT:
821 return LPCC::ICC_UGT;
822 case ISD::SETLT:
823 if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS))
824 if (RHSC->getZExtValue() == 0)
825 // X < 0 -> is_minus(X)
826 return LPCC::ICC_MI;
827 return LPCC::ICC_LT;
828 case ISD::SETULT:
829 return LPCC::ICC_ULT;
830 case ISD::SETLE:
831 if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS))
832 if (RHSC->getZExtValue() == 0xFFFFFFFF) {
833 // X <= -1 -> X < 0 -> is_minus(X)
834 RHS = DAG.getConstant(0, DL, RHS.getValueType());
835 return LPCC::ICC_MI;
836 }
837 return LPCC::ICC_LE;
838 case ISD::SETULE:
839 return LPCC::ICC_ULE;
840 case ISD::SETGE:
841 if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS))
842 if (RHSC->getZExtValue() == 0)
843 // X >= 0 -> is_plus(X)
844 return LPCC::ICC_PL;
845 return LPCC::ICC_GE;
846 case ISD::SETUGE:
847 return LPCC::ICC_UGE;
848 case ISD::SETNE:
849 return LPCC::ICC_NE;
850 case ISD::SETONE:
851 case ISD::SETUNE:
852 case ISD::SETOGE:
853 case ISD::SETOLE:
854 case ISD::SETOLT:
855 case ISD::SETOGT:
856 case ISD::SETOEQ:
857 case ISD::SETUEQ:
858 case ISD::SETO:
859 case ISD::SETUO:
860 llvm_unreachable("Unsupported comparison.");
861 default:
862 llvm_unreachable("Unknown integer condition code!");
863 }
864}
865
867 SDValue Chain = Op.getOperand(0);
868 SDValue Cond = Op.getOperand(1);
869 SDValue LHS = Op.getOperand(2);
870 SDValue RHS = Op.getOperand(3);
871 SDValue Dest = Op.getOperand(4);
872 SDLoc DL(Op);
873
875 SDValue TargetCC = DAG.getConstant(CC, DL, MVT::i32);
876 SDValue Glue = DAG.getNode(LanaiISD::SET_FLAG, DL, MVT::Glue, LHS, RHS);
877
878 return DAG.getNode(LanaiISD::BR_CC, DL, Op.getValueType(), Chain, Dest,
879 TargetCC, Glue);
880}
881
883 EVT VT = Op->getValueType(0);
884 if (VT != MVT::i32)
885 return SDValue();
886
887 ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op->getOperand(1));
888 if (!C)
889 return SDValue();
890
891 int64_t MulAmt = C->getSExtValue();
892 int32_t HighestOne = -1;
893 uint32_t NonzeroEntries = 0;
894 int SignedDigit[32] = {0};
895
896 // Convert to non-adjacent form (NAF) signed-digit representation.
897 // NAF is a signed-digit form where no adjacent digits are non-zero. It is the
898 // minimal Hamming weight representation of a number (on average 1/3 of the
899 // digits will be non-zero vs 1/2 for regular binary representation). And as
900 // the non-zero digits will be the only digits contributing to the instruction
901 // count, this is desirable. The next loop converts it to NAF (following the
902 // approach in 'Guide to Elliptic Curve Cryptography' [ISBN: 038795273X]) by
903 // choosing the non-zero coefficients such that the resulting quotient is
904 // divisible by 2 which will cause the next coefficient to be zero.
905 int64_t E = std::abs(MulAmt);
906 int S = (MulAmt < 0 ? -1 : 1);
907 int I = 0;
908 while (E > 0) {
909 int ZI = 0;
910 if (E % 2 == 1) {
911 ZI = 2 - (E % 4);
912 if (ZI != 0)
913 ++NonzeroEntries;
914 }
915 SignedDigit[I] = S * ZI;
916 if (SignedDigit[I] == 1)
917 HighestOne = I;
918 E = (E - ZI) / 2;
919 ++I;
920 }
921
922 // Compute number of instructions required. Due to differences in lowering
923 // between the different processors this count is not exact.
924 // Start by assuming a shift and a add/sub for every non-zero entry (hence
925 // every non-zero entry requires 1 shift and 1 add/sub except for the first
926 // entry).
927 int32_t InstrRequired = 2 * NonzeroEntries - 1;
928 // Correct possible over-adding due to shift by 0 (which is not emitted).
929 if (std::abs(MulAmt) % 2 == 1)
930 --InstrRequired;
931 // Return if the form generated would exceed the instruction threshold.
932 if (InstrRequired > LanaiLowerConstantMulThreshold)
933 return SDValue();
934
935 SDValue Res;
936 SDLoc DL(Op);
937 SDValue V = Op->getOperand(0);
938
939 // Initialize the running sum. Set the running sum to the maximal shifted
940 // positive value (i.e., largest i such that zi == 1 and MulAmt has V<<i as a
941 // term NAF).
942 if (HighestOne == -1)
943 Res = DAG.getConstant(0, DL, MVT::i32);
944 else {
945 Res = DAG.getNode(ISD::SHL, DL, VT, V,
946 DAG.getConstant(HighestOne, DL, MVT::i32));
947 SignedDigit[HighestOne] = 0;
948 }
949
950 // Assemble multiplication from shift, add, sub using NAF form and running
951 // sum.
952 for (unsigned int I = 0; I < std::size(SignedDigit); ++I) {
953 if (SignedDigit[I] == 0)
954 continue;
955
956 // Shifted multiplicand (v<<i).
957 SDValue Op =
958 DAG.getNode(ISD::SHL, DL, VT, V, DAG.getConstant(I, DL, MVT::i32));
959 if (SignedDigit[I] == 1)
960 Res = DAG.getNode(ISD::ADD, DL, VT, Res, Op);
961 else if (SignedDigit[I] == -1)
962 Res = DAG.getNode(ISD::SUB, DL, VT, Res, Op);
963 }
964 return Res;
965}
966
968 SDValue LHS = Op.getOperand(0);
969 SDValue RHS = Op.getOperand(1);
970 SDValue Cond = Op.getOperand(2);
971 SDLoc DL(Op);
972
974 SDValue TargetCC = DAG.getConstant(CC, DL, MVT::i32);
975 SDValue Glue = DAG.getNode(LanaiISD::SET_FLAG, DL, MVT::Glue, LHS, RHS);
976
977 return DAG.getNode(LanaiISD::SETCC, DL, Op.getValueType(), TargetCC, Glue);
978}
979
981 SelectionDAG &DAG) const {
982 SDValue LHS = Op.getOperand(0);
983 SDValue RHS = Op.getOperand(1);
984 SDValue TrueV = Op.getOperand(2);
985 SDValue FalseV = Op.getOperand(3);
986 SDValue Cond = Op.getOperand(4);
987 SDLoc DL(Op);
988
990 SDValue TargetCC = DAG.getConstant(CC, DL, MVT::i32);
991 SDValue Glue = DAG.getNode(LanaiISD::SET_FLAG, DL, MVT::Glue, LHS, RHS);
992
993 return DAG.getNode(LanaiISD::SELECT_CC, DL, Op.getValueType(), TrueV, FalseV,
994 TargetCC, Glue);
995}
996
1000
1001 SDLoc DL(Op);
1002 SDValue FI = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(),
1004
1005 // vastart just stores the address of the VarArgsFrameIndex slot into the
1006 // memory location argument.
1007 const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
1008 return DAG.getStore(Op.getOperand(0), DL, FI, Op.getOperand(1),
1009 MachinePointerInfo(SV));
1010}
1011
1013 SelectionDAG &DAG) const {
1014 SDValue Chain = Op.getOperand(0);
1015 SDValue Size = Op.getOperand(1);
1016 SDLoc DL(Op);
1017
1019
1020 // Get a reference to the stack pointer.
1021 SDValue StackPointer = DAG.getCopyFromReg(Chain, DL, SPReg, MVT::i32);
1022
1023 // Subtract the dynamic size from the actual stack size to
1024 // obtain the new stack size.
1025 SDValue Sub = DAG.getNode(ISD::SUB, DL, MVT::i32, StackPointer, Size);
1026
1027 // For Lanai, the outgoing memory arguments area should be on top of the
1028 // alloca area on the stack i.e., the outgoing memory arguments should be
1029 // at a lower address than the alloca area. Move the alloca area down the
1030 // stack by adding back the space reserved for outgoing arguments to SP
1031 // here.
1032 //
1033 // We do not know what the size of the outgoing args is at this point.
1034 // So, we add a pseudo instruction ADJDYNALLOC that will adjust the
1035 // stack pointer. We replace this instruction with on that has the correct,
1036 // known offset in emitPrologue().
1037 SDValue ArgAdjust = DAG.getNode(LanaiISD::ADJDYNALLOC, DL, MVT::i32, Sub);
1038
1039 // The Sub result contains the new stack start address, so it
1040 // must be placed in the stack pointer register.
1041 SDValue CopyChain = DAG.getCopyToReg(Chain, DL, SPReg, Sub);
1042
1043 SDValue Ops[2] = {ArgAdjust, CopyChain};
1044 return DAG.getMergeValues(Ops, DL);
1045}
1046
1048 SelectionDAG &DAG) const {
1050 MachineFrameInfo &MFI = MF.getFrameInfo();
1051 MFI.setReturnAddressIsTaken(true);
1052
1053 EVT VT = Op.getValueType();
1054 SDLoc DL(Op);
1055 unsigned Depth = Op.getConstantOperandVal(0);
1056 if (Depth) {
1057 SDValue FrameAddr = LowerFRAMEADDR(Op, DAG);
1058 const unsigned Offset = -4;
1059 SDValue Ptr = DAG.getNode(ISD::ADD, DL, VT, FrameAddr,
1061 return DAG.getLoad(VT, DL, DAG.getEntryNode(), Ptr, MachinePointerInfo());
1062 }
1063
1064 // Return the link register, which contains the return address.
1065 // Mark it an implicit live-in.
1066 Register Reg = MF.addLiveIn(TRI->getRARegister(), getRegClassFor(MVT::i32));
1067 return DAG.getCopyFromReg(DAG.getEntryNode(), DL, Reg, VT);
1068}
1069
1071 SelectionDAG &DAG) const {
1073 MFI.setFrameAddressIsTaken(true);
1074
1075 EVT VT = Op.getValueType();
1076 SDLoc DL(Op);
1077 SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), DL, Lanai::FP, VT);
1078 unsigned Depth = Op.getConstantOperandVal(0);
1079 while (Depth--) {
1080 const unsigned Offset = -8;
1081 SDValue Ptr = DAG.getNode(ISD::ADD, DL, VT, FrameAddr,
1083 FrameAddr =
1084 DAG.getLoad(VT, DL, DAG.getEntryNode(), Ptr, MachinePointerInfo());
1085 }
1086 return FrameAddr;
1087}
1088
1089const char *LanaiTargetLowering::getTargetNodeName(unsigned Opcode) const {
1090 switch (Opcode) {
1092 return "LanaiISD::ADJDYNALLOC";
1093 case LanaiISD::RET_GLUE:
1094 return "LanaiISD::RET_GLUE";
1095 case LanaiISD::CALL:
1096 return "LanaiISD::CALL";
1098 return "LanaiISD::SELECT_CC";
1099 case LanaiISD::SETCC:
1100 return "LanaiISD::SETCC";
1101 case LanaiISD::SUBBF:
1102 return "LanaiISD::SUBBF";
1103 case LanaiISD::SET_FLAG:
1104 return "LanaiISD::SET_FLAG";
1105 case LanaiISD::BR_CC:
1106 return "LanaiISD::BR_CC";
1107 case LanaiISD::Wrapper:
1108 return "LanaiISD::Wrapper";
1109 case LanaiISD::HI:
1110 return "LanaiISD::HI";
1111 case LanaiISD::LO:
1112 return "LanaiISD::LO";
1113 case LanaiISD::SMALL:
1114 return "LanaiISD::SMALL";
1115 default:
1116 return nullptr;
1117 }
1118}
1119
1121 SelectionDAG &DAG) const {
1122 SDLoc DL(Op);
1123 ConstantPoolSDNode *N = cast<ConstantPoolSDNode>(Op);
1124 const Constant *C = N->getConstVal();
1125 const LanaiTargetObjectFile *TLOF =
1126 static_cast<const LanaiTargetObjectFile *>(
1128
1129 // If the code model is small or constant will be placed in the small section,
1130 // then assume address will fit in 21-bits.
1133 SDValue Small = DAG.getTargetConstantPool(
1134 C, MVT::i32, N->getAlign(), N->getOffset(), LanaiII::MO_NO_FLAG);
1135 return DAG.getNode(ISD::OR, DL, MVT::i32,
1136 DAG.getRegister(Lanai::R0, MVT::i32),
1137 DAG.getNode(LanaiISD::SMALL, DL, MVT::i32, Small));
1138 } else {
1139 uint8_t OpFlagHi = LanaiII::MO_ABS_HI;
1140 uint8_t OpFlagLo = LanaiII::MO_ABS_LO;
1141
1142 SDValue Hi = DAG.getTargetConstantPool(C, MVT::i32, N->getAlign(),
1143 N->getOffset(), OpFlagHi);
1144 SDValue Lo = DAG.getTargetConstantPool(C, MVT::i32, N->getAlign(),
1145 N->getOffset(), OpFlagLo);
1146 Hi = DAG.getNode(LanaiISD::HI, DL, MVT::i32, Hi);
1147 Lo = DAG.getNode(LanaiISD::LO, DL, MVT::i32, Lo);
1148 SDValue Result = DAG.getNode(ISD::OR, DL, MVT::i32, Hi, Lo);
1149 return Result;
1150 }
1151}
1152
1154 SelectionDAG &DAG) const {
1155 SDLoc DL(Op);
1156 const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
1157 int64_t Offset = cast<GlobalAddressSDNode>(Op)->getOffset();
1158
1159 const LanaiTargetObjectFile *TLOF =
1160 static_cast<const LanaiTargetObjectFile *>(
1162
1163 // If the code model is small or global variable will be placed in the small
1164 // section, then assume address will fit in 21-bits.
1165 const GlobalObject *GO = GV->getAliaseeObject();
1166 if (TLOF->isGlobalInSmallSection(GO, getTargetMachine())) {
1167 SDValue Small = DAG.getTargetGlobalAddress(
1169 return DAG.getNode(ISD::OR, DL, MVT::i32,
1170 DAG.getRegister(Lanai::R0, MVT::i32),
1171 DAG.getNode(LanaiISD::SMALL, DL, MVT::i32, Small));
1172 } else {
1173 uint8_t OpFlagHi = LanaiII::MO_ABS_HI;
1174 uint8_t OpFlagLo = LanaiII::MO_ABS_LO;
1175
1176 // Create the TargetGlobalAddress node, folding in the constant offset.
1178 GV, DL, getPointerTy(DAG.getDataLayout()), Offset, OpFlagHi);
1180 GV, DL, getPointerTy(DAG.getDataLayout()), Offset, OpFlagLo);
1181 Hi = DAG.getNode(LanaiISD::HI, DL, MVT::i32, Hi);
1182 Lo = DAG.getNode(LanaiISD::LO, DL, MVT::i32, Lo);
1183 return DAG.getNode(ISD::OR, DL, MVT::i32, Hi, Lo);
1184 }
1185}
1186
1188 SelectionDAG &DAG) const {
1189 SDLoc DL(Op);
1190 const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();
1191
1192 uint8_t OpFlagHi = LanaiII::MO_ABS_HI;
1193 uint8_t OpFlagLo = LanaiII::MO_ABS_LO;
1194
1195 SDValue Hi = DAG.getBlockAddress(BA, MVT::i32, true, OpFlagHi);
1196 SDValue Lo = DAG.getBlockAddress(BA, MVT::i32, true, OpFlagLo);
1197 Hi = DAG.getNode(LanaiISD::HI, DL, MVT::i32, Hi);
1198 Lo = DAG.getNode(LanaiISD::LO, DL, MVT::i32, Lo);
1199 SDValue Result = DAG.getNode(ISD::OR, DL, MVT::i32, Hi, Lo);
1200 return Result;
1201}
1202
1204 SelectionDAG &DAG) const {
1205 SDLoc DL(Op);
1206 JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
1207
1208 // If the code model is small assume address will fit in 21-bits.
1210 SDValue Small = DAG.getTargetJumpTable(
1211 JT->getIndex(), getPointerTy(DAG.getDataLayout()), LanaiII::MO_NO_FLAG);
1212 return DAG.getNode(ISD::OR, DL, MVT::i32,
1213 DAG.getRegister(Lanai::R0, MVT::i32),
1214 DAG.getNode(LanaiISD::SMALL, DL, MVT::i32, Small));
1215 } else {
1216 uint8_t OpFlagHi = LanaiII::MO_ABS_HI;
1217 uint8_t OpFlagLo = LanaiII::MO_ABS_LO;
1218
1220 JT->getIndex(), getPointerTy(DAG.getDataLayout()), OpFlagHi);
1222 JT->getIndex(), getPointerTy(DAG.getDataLayout()), OpFlagLo);
1223 Hi = DAG.getNode(LanaiISD::HI, DL, MVT::i32, Hi);
1224 Lo = DAG.getNode(LanaiISD::LO, DL, MVT::i32, Lo);
1225 SDValue Result = DAG.getNode(ISD::OR, DL, MVT::i32, Hi, Lo);
1226 return Result;
1227 }
1228}
1229
1231 SelectionDAG &DAG) const {
1232 EVT VT = Op.getValueType();
1233 unsigned VTBits = VT.getSizeInBits();
1234 SDLoc dl(Op);
1235 assert(Op.getNumOperands() == 3 && "Unexpected SHL!");
1236 SDValue ShOpLo = Op.getOperand(0);
1237 SDValue ShOpHi = Op.getOperand(1);
1238 SDValue ShAmt = Op.getOperand(2);
1239
1240 // Performs the following for (ShOpLo + (ShOpHi << 32)) << ShAmt:
1241 // LoBitsForHi = (ShAmt == 0) ? 0 : (ShOpLo >> (32-ShAmt))
1242 // HiBitsForHi = ShOpHi << ShAmt
1243 // Hi = (ShAmt >= 32) ? (ShOpLo << (ShAmt-32)) : (LoBitsForHi | HiBitsForHi)
1244 // Lo = (ShAmt >= 32) ? 0 : (ShOpLo << ShAmt)
1245 // return (Hi << 32) | Lo;
1246
1247 SDValue RevShAmt = DAG.getNode(ISD::SUB, dl, MVT::i32,
1248 DAG.getConstant(VTBits, dl, MVT::i32), ShAmt);
1249 SDValue LoBitsForHi = DAG.getNode(ISD::SRL, dl, VT, ShOpLo, RevShAmt);
1250
1251 // If ShAmt == 0, we just calculated "(SRL ShOpLo, 32)" which is "undef". We
1252 // wanted 0, so CSEL it directly.
1253 SDValue Zero = DAG.getConstant(0, dl, MVT::i32);
1254 SDValue SetCC = DAG.getSetCC(dl, MVT::i32, ShAmt, Zero, ISD::SETEQ);
1255 LoBitsForHi = DAG.getSelect(dl, MVT::i32, SetCC, Zero, LoBitsForHi);
1256
1257 SDValue ExtraShAmt = DAG.getNode(ISD::SUB, dl, MVT::i32, ShAmt,
1258 DAG.getConstant(VTBits, dl, MVT::i32));
1259 SDValue HiBitsForHi = DAG.getNode(ISD::SHL, dl, VT, ShOpHi, ShAmt);
1260 SDValue HiForNormalShift =
1261 DAG.getNode(ISD::OR, dl, VT, LoBitsForHi, HiBitsForHi);
1262
1263 SDValue HiForBigShift = DAG.getNode(ISD::SHL, dl, VT, ShOpLo, ExtraShAmt);
1264
1265 SetCC = DAG.getSetCC(dl, MVT::i32, ExtraShAmt, Zero, ISD::SETGE);
1266 SDValue Hi =
1267 DAG.getSelect(dl, MVT::i32, SetCC, HiForBigShift, HiForNormalShift);
1268
1269 // Lanai shifts of larger than register sizes are wrapped rather than
1270 // clamped, so we can't just emit "lo << b" if b is too big.
1271 SDValue LoForNormalShift = DAG.getNode(ISD::SHL, dl, VT, ShOpLo, ShAmt);
1272 SDValue Lo = DAG.getSelect(
1273 dl, MVT::i32, SetCC, DAG.getConstant(0, dl, MVT::i32), LoForNormalShift);
1274
1275 SDValue Ops[2] = {Lo, Hi};
1276 return DAG.getMergeValues(Ops, dl);
1277}
1278
1280 SelectionDAG &DAG) const {
1281 MVT VT = Op.getSimpleValueType();
1282 unsigned VTBits = VT.getSizeInBits();
1283 SDLoc dl(Op);
1284 SDValue ShOpLo = Op.getOperand(0);
1285 SDValue ShOpHi = Op.getOperand(1);
1286 SDValue ShAmt = Op.getOperand(2);
1287
1288 // Performs the following for a >> b:
1289 // unsigned r_high = a_high >> b;
1290 // r_high = (32 - b <= 0) ? 0 : r_high;
1291 //
1292 // unsigned r_low = a_low >> b;
1293 // r_low = (32 - b <= 0) ? r_high : r_low;
1294 // r_low = (b == 0) ? r_low : r_low | (a_high << (32 - b));
1295 // return (unsigned long long)r_high << 32 | r_low;
1296 // Note: This takes advantage of Lanai's shift behavior to avoid needing to
1297 // mask the shift amount.
1298
1299 SDValue Zero = DAG.getConstant(0, dl, MVT::i32);
1300 SDValue NegatedPlus32 = DAG.getNode(
1301 ISD::SUB, dl, MVT::i32, DAG.getConstant(VTBits, dl, MVT::i32), ShAmt);
1302 SDValue SetCC = DAG.getSetCC(dl, MVT::i32, NegatedPlus32, Zero, ISD::SETLE);
1303
1304 SDValue Hi = DAG.getNode(ISD::SRL, dl, MVT::i32, ShOpHi, ShAmt);
1305 Hi = DAG.getSelect(dl, MVT::i32, SetCC, Zero, Hi);
1306
1307 SDValue Lo = DAG.getNode(ISD::SRL, dl, MVT::i32, ShOpLo, ShAmt);
1308 Lo = DAG.getSelect(dl, MVT::i32, SetCC, Hi, Lo);
1309 SDValue CarryBits =
1310 DAG.getNode(ISD::SHL, dl, MVT::i32, ShOpHi, NegatedPlus32);
1311 SDValue ShiftIsZero = DAG.getSetCC(dl, MVT::i32, ShAmt, Zero, ISD::SETEQ);
1312 Lo = DAG.getSelect(dl, MVT::i32, ShiftIsZero, Lo,
1313 DAG.getNode(ISD::OR, dl, MVT::i32, Lo, CarryBits));
1314
1315 SDValue Ops[2] = {Lo, Hi};
1316 return DAG.getMergeValues(Ops, dl);
1317}
1318
1319// Helper function that checks if N is a null or all ones constant.
1320static inline bool isZeroOrAllOnes(SDValue N, bool AllOnes) {
1322}
1323
1324// Return true if N is conditionally 0 or all ones.
1325// Detects these expressions where cc is an i1 value:
1326//
1327// (select cc 0, y) [AllOnes=0]
1328// (select cc y, 0) [AllOnes=0]
1329// (zext cc) [AllOnes=0]
1330// (sext cc) [AllOnes=0/1]
1331// (select cc -1, y) [AllOnes=1]
1332// (select cc y, -1) [AllOnes=1]
1333//
1334// * AllOnes determines whether to check for an all zero (AllOnes false) or an
1335// all ones operand (AllOnes true).
1336// * Invert is set when N is the all zero/ones constant when CC is false.
1337// * OtherOp is set to the alternative value of N.
1338//
1339// For example, for (select cc X, Y) and AllOnes = 0 if:
1340// * X = 0, Invert = False and OtherOp = Y
1341// * Y = 0, Invert = True and OtherOp = X
1343 bool &Invert, SDValue &OtherOp,
1344 SelectionDAG &DAG) {
1345 switch (N->getOpcode()) {
1346 default:
1347 return false;
1348 case ISD::SELECT: {
1349 CC = N->getOperand(0);
1350 SDValue N1 = N->getOperand(1);
1351 SDValue N2 = N->getOperand(2);
1352 if (isZeroOrAllOnes(N1, AllOnes)) {
1353 Invert = false;
1354 OtherOp = N2;
1355 return true;
1356 }
1357 if (isZeroOrAllOnes(N2, AllOnes)) {
1358 Invert = true;
1359 OtherOp = N1;
1360 return true;
1361 }
1362 return false;
1363 }
1364 case ISD::ZERO_EXTEND: {
1365 // (zext cc) can never be the all ones value.
1366 if (AllOnes)
1367 return false;
1368 CC = N->getOperand(0);
1369 if (CC.getValueType() != MVT::i1)
1370 return false;
1371 SDLoc dl(N);
1372 EVT VT = N->getValueType(0);
1373 OtherOp = DAG.getConstant(1, dl, VT);
1374 Invert = true;
1375 return true;
1376 }
1377 case ISD::SIGN_EXTEND: {
1378 CC = N->getOperand(0);
1379 if (CC.getValueType() != MVT::i1)
1380 return false;
1381 SDLoc dl(N);
1382 EVT VT = N->getValueType(0);
1383 Invert = !AllOnes;
1384 if (AllOnes)
1385 // When looking for an AllOnes constant, N is an sext, and the 'other'
1386 // value is 0.
1387 OtherOp = DAG.getConstant(0, dl, VT);
1388 else
1389 OtherOp = DAG.getAllOnesConstant(dl, VT);
1390 return true;
1391 }
1392 }
1393}
1394
1395// Combine a constant select operand into its use:
1396//
1397// (add (select cc, 0, c), x) -> (select cc, x, (add, x, c))
1398// (sub x, (select cc, 0, c)) -> (select cc, x, (sub, x, c))
1399// (and (select cc, -1, c), x) -> (select cc, x, (and, x, c)) [AllOnes=1]
1400// (or (select cc, 0, c), x) -> (select cc, x, (or, x, c))
1401// (xor (select cc, 0, c), x) -> (select cc, x, (xor, x, c))
1402//
1403// The transform is rejected if the select doesn't have a constant operand that
1404// is null, or all ones when AllOnes is set.
1405//
1406// Also recognize sext/zext from i1:
1407//
1408// (add (zext cc), x) -> (select cc (add x, 1), x)
1409// (add (sext cc), x) -> (select cc (add x, -1), x)
1410//
1411// These transformations eventually create predicated instructions.
1414 bool AllOnes) {
1415 SelectionDAG &DAG = DCI.DAG;
1416 EVT VT = N->getValueType(0);
1417 SDValue NonConstantVal;
1418 SDValue CCOp;
1419 bool SwapSelectOps;
1420 if (!isConditionalZeroOrAllOnes(Slct.getNode(), AllOnes, CCOp, SwapSelectOps,
1421 NonConstantVal, DAG))
1422 return SDValue();
1423
1424 // Slct is now know to be the desired identity constant when CC is true.
1425 SDValue TrueVal = OtherOp;
1426 SDValue FalseVal =
1427 DAG.getNode(N->getOpcode(), SDLoc(N), VT, OtherOp, NonConstantVal);
1428 // Unless SwapSelectOps says CC should be false.
1429 if (SwapSelectOps)
1430 std::swap(TrueVal, FalseVal);
1431
1432 return DAG.getNode(ISD::SELECT, SDLoc(N), VT, CCOp, TrueVal, FalseVal);
1433}
1434
1435// Attempt combineSelectAndUse on each operand of a commutative operator N.
1436static SDValue
1438 bool AllOnes) {
1439 SDValue N0 = N->getOperand(0);
1440 SDValue N1 = N->getOperand(1);
1441 if (N0.getNode()->hasOneUse())
1442 if (SDValue Result = combineSelectAndUse(N, N0, N1, DCI, AllOnes))
1443 return Result;
1444 if (N1.getNode()->hasOneUse())
1445 if (SDValue Result = combineSelectAndUse(N, N1, N0, DCI, AllOnes))
1446 return Result;
1447 return SDValue();
1448}
1449
1450// PerformSUBCombine - Target-specific dag combine xforms for ISD::SUB.
1453 SDValue N0 = N->getOperand(0);
1454 SDValue N1 = N->getOperand(1);
1455
1456 // fold (sub x, (select cc, 0, c)) -> (select cc, x, (sub, x, c))
1457 if (N1.getNode()->hasOneUse())
1458 if (SDValue Result = combineSelectAndUse(N, N1, N0, DCI, /*AllOnes=*/false))
1459 return Result;
1460
1461 return SDValue();
1462}
1463
1465 DAGCombinerInfo &DCI) const {
1466 switch (N->getOpcode()) {
1467 default:
1468 break;
1469 case ISD::ADD:
1470 case ISD::OR:
1471 case ISD::XOR:
1472 return combineSelectAndUseCommutative(N, DCI, /*AllOnes=*/false);
1473 case ISD::AND:
1474 return combineSelectAndUseCommutative(N, DCI, /*AllOnes=*/true);
1475 case ISD::SUB:
1476 return PerformSUBCombine(N, DCI);
1477 }
1478
1479 return SDValue();
1480}
1481
1483 const SDValue Op, KnownBits &Known, const APInt &DemandedElts,
1484 const SelectionDAG &DAG, unsigned Depth) const {
1485 unsigned BitWidth = Known.getBitWidth();
1486 switch (Op.getOpcode()) {
1487 default:
1488 break;
1489 case LanaiISD::SETCC:
1490 Known = KnownBits(BitWidth);
1491 Known.Zero.setBits(1, BitWidth);
1492 break;
1494 KnownBits Known2;
1495 Known = DAG.computeKnownBits(Op->getOperand(0), Depth + 1);
1496 Known2 = DAG.computeKnownBits(Op->getOperand(1), Depth + 1);
1497 Known = Known.intersectWith(Known2);
1498 break;
1499 }
1500}
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
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
#define LLVM_DEBUG(...)
Definition: Debug.h:106
uint64_t Size
#define RegName(no)
static unsigned NumFixedArgs
static bool CC_Lanai32_VarArg(unsigned ValNo, MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, CCState &State)
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))
#define I(x, y, z)
Definition: MD5.cpp:58
#define G(x, y, z)
Definition: MD5.cpp:56
unsigned const TargetRegisterInfo * TRI
static CodeModel::Model getCodeModel(const PPCSubtarget &S, const TargetMachine &TM, const MachineOperand &MO)
static constexpr Register SPReg
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
Value * RHS
Value * LHS
Class for arbitrary precision integers.
Definition: APInt.h:78
void setBits(unsigned loBit, unsigned hiBit)
Set the bits from loBit (inclusive) to hiBit (exclusive) to 1.
Definition: APInt.h:1367
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
The address of a basic block.
Definition: Constants.h:893
CCState - This class holds information needed while lowering arguments and return values.
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 ...
int64_t AllocateStack(unsigned Size, Align Alignment)
AllocateStack - Allocate a chunk of stack space with the specified size and alignment.
void addLoc(const CCValAssign &V)
CCValAssign - Represent assignment of one arg/retval to a location.
bool isRegLoc() const
Register getLocReg() const
LocInfo getLocInfo() const
static CCValAssign getMem(unsigned ValNo, MVT ValVT, int64_t Offset, MVT LocVT, LocInfo HTP, bool IsCustom=false)
bool isMemLoc() const
int64_t getLocMemOffset() const
This is an important base class in LLVM.
Definition: Constant.h:42
This class represents an Operation in the Expression.
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
Definition: DerivedTypes.h:144
FunctionType * getFunctionType() const
Returns the FunctionType for me.
Definition: Function.h:216
bool hasStructRetAttr() const
Determine if the function returns a structure through first or second pointer argument.
Definition: Function.h:688
const GlobalObject * getAliaseeObject() const
Definition: Globals.cpp:400
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:67
const LanaiRegisterInfo * getRegisterInfo() const override
const char * getTargetNodeName(unsigned Opcode) const override
This method returns the name of a target specific DAG node.
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 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.
int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)
Create a new object at a fixed location on the stack.
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...
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
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
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
Definition: SelectionDAG.h:228
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
Definition: SelectionDAG.h:748
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, Register Reg, SDValue N)
Definition: SelectionDAG.h:799
SDValue getMergeValues(ArrayRef< SDValue > Ops, const SDLoc &dl)
Create a MERGE_VALUES node from the given operands.
SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
SDValue getAllOnesConstant(const SDLoc &DL, EVT VT, bool IsTarget=false, bool IsOpaque=false)
SDValue getMemcpy(SDValue Chain, const SDLoc &dl, SDValue Dst, SDValue Src, SDValue Size, Align Alignment, bool isVol, bool AlwaysInline, const CallInst *CI, std::optional< bool > OverrideTailCall, MachinePointerInfo DstPtrInfo, MachinePointerInfo SrcPtrInfo, const AAMDNodes &AAInfo=AAMDNodes(), AAResults *AA=nullptr)
SDValue getSetCC(const SDLoc &DL, EVT VT, SDValue LHS, SDValue RHS, ISD::CondCode Cond, SDValue Chain=SDValue(), bool IsSignaling=false)
Helper function to make it easier to build SetCC's if you just have an ISD::CondCode instead of an SD...
SDValue getRegister(Register Reg, EVT VT)
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 getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
Definition: SelectionDAG.h:758
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)
Definition: SelectionDAG.h:825
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
Definition: SelectionDAG.h:495
SDValue getConstant(uint64_t Val, const SDLoc &DL, EVT VT, bool isTarget=false, bool isOpaque=false)
Create a ConstantSDNode wrapping a constant value.
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 ...
SDValue getBlockAddress(const BlockAddress *BA, EVT VT, int64_t Offset=0, bool isTarget=false, unsigned TargetFlags=0)
SDValue getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
SDValue getValueType(EVT)
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)
Definition: SelectionDAG.h:698
MachineFunction & getMachineFunction() const
Definition: SelectionDAG.h:490
SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
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.
SDValue getRegisterMask(const uint32_t *RegMask)
LLVMContext * getContext() const
Definition: SelectionDAG.h:508
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)
Definition: SelectionDAG.h:765
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
Definition: SelectionDAG.h:578
bool empty() const
Definition: SmallVector.h:81
size_t size() const
Definition: SmallVector.h:78
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:573
void push_back(const T &Elt)
Definition: SmallVector.h:413
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:150
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:44
StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:69
R Default(T Value)
Definition: StringSwitch.h:182
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 setLibcallCallingConv(RTLIB::Libcall Call, CallingConv::ID CC)
Set the CallingConv that should be used for the specified libcall.
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...
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
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.
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.
Definition: TargetMachine.h:77
virtual TargetLoweringObjectFile * getObjFileLowering() const
CodeModel::Model getCodeModel() const
Returns the code model.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
LLVM Value Representation.
Definition: Value.h:74
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
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.
Definition: BitmaskEnum.h:125
@ 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:780
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
Definition: ISDOpcodes.h:1197
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
Definition: ISDOpcodes.h:1193
@ SMUL_LOHI
SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing a signed/unsigned value of type i[2...
Definition: ISDOpcodes.h:257
@ BSWAP
Byte Swap and Counting operators.
Definition: ISDOpcodes.h:744
@ VAEND
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE.
Definition: ISDOpcodes.h:1226
@ ADD
Simple integer binary arithmetic operators.
Definition: ISDOpcodes.h:246
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
Definition: ISDOpcodes.h:814
@ GlobalAddress
Definition: ISDOpcodes.h:78
@ SDIVREM
SDIVREM/UDIVREM - Divide two integers and produce both a quotient and remainder result.
Definition: ISDOpcodes.h:262
@ SIGN_EXTEND
Conversion operators.
Definition: ISDOpcodes.h:805
@ BR_CC
BR_CC - Conditional branch.
Definition: ISDOpcodes.h:1148
@ BR_JT
BR_JT - Jumptable branch.
Definition: ISDOpcodes.h:1127
@ SELECT
Select(COND, TRUEVAL, FALSEVAL).
Definition: ISDOpcodes.h:757
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
Definition: ISDOpcodes.h:1222
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
Definition: ISDOpcodes.h:674
@ SHL
Shift and rotation operations.
Definition: ISDOpcodes.h:735
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
Definition: ISDOpcodes.h:811
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
Definition: ISDOpcodes.h:772
@ DYNAMIC_STACKALLOC
DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned to a specified boundary.
Definition: ISDOpcodes.h:1112
@ ConstantPool
Definition: ISDOpcodes.h:82
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
Definition: ISDOpcodes.h:849
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
Definition: ISDOpcodes.h:100
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition: ISDOpcodes.h:709
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
Definition: ISDOpcodes.h:52
@ TRUNCATE
TRUNCATE - Completely drop the high bits.
Definition: ISDOpcodes.h:817
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
Definition: ISDOpcodes.h:1217
@ BRCOND
BRCOND - Conditional branch.
Definition: ISDOpcodes.h:1141
@ BlockAddress
Definition: ISDOpcodes.h:84
@ SHL_PARTS
SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded integer shift operations.
Definition: ISDOpcodes.h:794
@ AssertSext
AssertSext, AssertZext - These nodes record if a register contains a value that has already been zero...
Definition: ISDOpcodes.h:61
@ AssertZext
Definition: ISDOpcodes.h:62
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
Definition: ISDOpcodes.h:1602
Libcall
RTLIB::Libcall enum - This enum defines all of the runtime library calls the backend can emit.
Reg
All possible values of the reg field in the ModR/M byte.
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:443
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:480
bool isNullConstant(SDValue V)
Returns true if V is a constant integer zero.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:167
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
constexpr unsigned BitWidth
Definition: BitmaskEnum.h:217
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:860
#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:368
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition: ValueTypes.h:311
unsigned getBitWidth() const
Get the bit width of this value.
Definition: KnownBits.h:43
KnownBits intersectWith(const KnownBits &RHS) const
Returns KnownBits information that is known to be true for both this and RHS.
Definition: KnownBits.h:303
unsigned getRARegister() const
const uint32_t * getCallPreservedMask(const MachineFunction &MF, CallingConv::ID) const override
This class contains a discriminated union of information about pointers in memory operands,...
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
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
SmallVector< SDValue, 32 > OutVals