LLVM 22.0.0git
ARCISelLowering.cpp
Go to the documentation of this file.
1//===- ARCISelLowering.cpp - ARC DAG Lowering Impl --------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the ARCTargetLowering class.
10//
11//===----------------------------------------------------------------------===//
12
13#include "ARCISelLowering.h"
14#include "ARC.h"
16#include "ARCSelectionDAGInfo.h"
17#include "ARCSubtarget.h"
18#include "ARCTargetMachine.h"
27#include "llvm/IR/CallingConv.h"
28#include "llvm/IR/Intrinsics.h"
29#include "llvm/Support/Debug.h"
30#include <algorithm>
31
32#define DEBUG_TYPE "arc-lower"
33
34using namespace llvm;
35
36static SDValue lowerCallResult(SDValue Chain, SDValue InGlue,
37 const SmallVectorImpl<CCValAssign> &RVLocs,
38 SDLoc dl, SelectionDAG &DAG,
40
42 switch (isdCC) {
43 case ISD::SETUEQ:
44 return ARCCC::EQ;
45 case ISD::SETUGT:
46 return ARCCC::HI;
47 case ISD::SETUGE:
48 return ARCCC::HS;
49 case ISD::SETULT:
50 return ARCCC::LO;
51 case ISD::SETULE:
52 return ARCCC::LS;
53 case ISD::SETUNE:
54 return ARCCC::NE;
55 case ISD::SETEQ:
56 return ARCCC::EQ;
57 case ISD::SETGT:
58 return ARCCC::GT;
59 case ISD::SETGE:
60 return ARCCC::GE;
61 case ISD::SETLT:
62 return ARCCC::LT;
63 case ISD::SETLE:
64 return ARCCC::LE;
65 case ISD::SETNE:
66 return ARCCC::NE;
67 default:
68 llvm_unreachable("Unhandled ISDCC code.");
69 }
70}
71
72void ARCTargetLowering::ReplaceNodeResults(SDNode *N,
74 SelectionDAG &DAG) const {
75 LLVM_DEBUG(dbgs() << "[ARC-ISEL] ReplaceNodeResults ");
76 LLVM_DEBUG(N->dump(&DAG));
77 LLVM_DEBUG(dbgs() << "; use_count=" << N->use_size() << "\n");
78
79 switch (N->getOpcode()) {
81 if (N->getValueType(0) == MVT::i64) {
82 // We read the TIMER0 and zero-extend it to 64-bits as the intrinsic
83 // requires.
84 SDValue V =
86 DAG.getVTList(MVT::i32, MVT::Other), N->getOperand(0));
87 SDValue Op = DAG.getNode(ISD::ZERO_EXTEND, SDLoc(N), MVT::i64, V);
88 Results.push_back(Op);
89 Results.push_back(V.getValue(1));
90 }
91 break;
92 default:
93 break;
94 }
95}
96
98 const ARCSubtarget &Subtarget)
99 : TargetLowering(TM), Subtarget(Subtarget) {
100 // Set up the register classes.
101 addRegisterClass(MVT::i32, &ARC::GPR32RegClass);
102
103 // Compute derived properties from the register classes
105
107
109
110 // Use i32 for setcc operations results (slt, sgt, ...).
113
114 for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc)
115 setOperationAction(Opc, MVT::i32, Expand);
116
117 // Operations to get us off of the ground.
118 // Basic.
124
129
130 // Need barrel shifter.
135
138
139 // Need multiplier
145
151
152 // Have pseudo instruction for frame addresses.
154 // Custom lower global addresses.
156
157 // Expand var-args ops.
162
163 // Other expansions
166
167 // Sign extend inreg
169
170 // TODO: Predicate these with `options.hasBitScan() ? Legal : Expand`
171 // when the HasBitScan predicate is available.
174
177 isTypeLegal(MVT::i64) ? Legal : Custom);
178
180}
181
182//===----------------------------------------------------------------------===//
183// Misc Lower Operation implementation
184//===----------------------------------------------------------------------===//
185
186SDValue ARCTargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const {
187 SDValue LHS = Op.getOperand(0);
188 SDValue RHS = Op.getOperand(1);
189 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
190 SDValue TVal = Op.getOperand(2);
191 SDValue FVal = Op.getOperand(3);
192 SDLoc dl(Op);
193 ARCCC::CondCode ArcCC = ISDCCtoARCCC(CC);
194 assert(LHS.getValueType() == MVT::i32 && "Only know how to SELECT_CC i32");
195 SDValue Cmp = DAG.getNode(ARCISD::CMP, dl, MVT::Glue, LHS, RHS);
196 return DAG.getNode(ARCISD::CMOV, dl, TVal.getValueType(), TVal, FVal,
197 DAG.getConstant(ArcCC, dl, MVT::i32), Cmp);
198}
199
200SDValue ARCTargetLowering::LowerSIGN_EXTEND_INREG(SDValue Op,
201 SelectionDAG &DAG) const {
202 SDValue Op0 = Op.getOperand(0);
203 SDLoc dl(Op);
204 assert(Op.getValueType() == MVT::i32 &&
205 "Unhandled target sign_extend_inreg.");
206 // These are legal
207 unsigned Width = cast<VTSDNode>(Op.getOperand(1))->getVT().getSizeInBits();
208 if (Width == 16 || Width == 8)
209 return Op;
210 if (Width >= 32) {
211 return {};
212 }
213 SDValue LS = DAG.getNode(ISD::SHL, dl, MVT::i32, Op0,
214 DAG.getConstant(32 - Width, dl, MVT::i32));
215 SDValue SR = DAG.getNode(ISD::SRA, dl, MVT::i32, LS,
216 DAG.getConstant(32 - Width, dl, MVT::i32));
217 return SR;
218}
219
220SDValue ARCTargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) const {
221 SDValue Chain = Op.getOperand(0);
222 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
223 SDValue LHS = Op.getOperand(2);
224 SDValue RHS = Op.getOperand(3);
225 SDValue Dest = Op.getOperand(4);
226 SDLoc dl(Op);
227 ARCCC::CondCode arcCC = ISDCCtoARCCC(CC);
228 assert(LHS.getValueType() == MVT::i32 && "Only know how to BR_CC i32");
229 return DAG.getNode(ARCISD::BRcc, dl, MVT::Other, Chain, Dest, LHS, RHS,
230 DAG.getConstant(arcCC, dl, MVT::i32));
231}
232
233SDValue ARCTargetLowering::LowerJumpTable(SDValue Op, SelectionDAG &DAG) const {
234 auto *N = cast<JumpTableSDNode>(Op);
235 SDValue GA = DAG.getTargetJumpTable(N->getIndex(), MVT::i32);
236 return DAG.getNode(ARCISD::GAWRAPPER, SDLoc(N), MVT::i32, GA);
237}
238
239#include "ARCGenCallingConv.inc"
240
241//===----------------------------------------------------------------------===//
242// Call Calling Convention Implementation
243//===----------------------------------------------------------------------===//
244
245/// ARC call implementation
246SDValue ARCTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
247 SmallVectorImpl<SDValue> &InVals) const {
248 SelectionDAG &DAG = CLI.DAG;
249 SDLoc &dl = CLI.DL;
251 SmallVectorImpl<SDValue> &OutVals = CLI.OutVals;
253 SDValue Chain = CLI.Chain;
254 SDValue Callee = CLI.Callee;
255 CallingConv::ID CallConv = CLI.CallConv;
256 bool IsVarArg = CLI.IsVarArg;
257 bool &IsTailCall = CLI.IsTailCall;
258
259 IsTailCall = false; // Do not support tail calls yet.
260
262 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs,
263 *DAG.getContext());
264
265 CCInfo.AnalyzeCallOperands(Outs, CC_ARC);
266
268 // Analyze return values to determine the number of bytes of stack required.
269 CCState RetCCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs,
270 *DAG.getContext());
271 RetCCInfo.AllocateStack(CCInfo.getStackSize(), Align(4));
272 RetCCInfo.AnalyzeCallResult(Ins, RetCC_ARC);
273
274 // Get a count of how many bytes are to be pushed on the stack.
275 unsigned NumBytes = RetCCInfo.getStackSize();
276
277 Chain = DAG.getCALLSEQ_START(Chain, NumBytes, 0, dl);
278
280 SmallVector<SDValue, 12> MemOpChains;
281
283 // Walk the register/memloc assignments, inserting copies/loads.
284 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
285 CCValAssign &VA = ArgLocs[i];
286 SDValue Arg = OutVals[i];
287
288 // Promote the value if needed.
289 switch (VA.getLocInfo()) {
290 default:
291 llvm_unreachable("Unknown loc info!");
293 break;
295 Arg = DAG.getNode(ISD::SIGN_EXTEND, dl, VA.getLocVT(), Arg);
296 break;
298 Arg = DAG.getNode(ISD::ZERO_EXTEND, dl, VA.getLocVT(), Arg);
299 break;
301 Arg = DAG.getNode(ISD::ANY_EXTEND, dl, VA.getLocVT(), Arg);
302 break;
303 }
304
305 // Arguments that can be passed on register must be kept at
306 // RegsToPass vector
307 if (VA.isRegLoc()) {
308 RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
309 } else {
310 assert(VA.isMemLoc() && "Must be register or memory argument.");
311 if (!StackPtr.getNode())
312 StackPtr = DAG.getCopyFromReg(Chain, dl, ARC::SP,
314 // Calculate the stack position.
315 SDValue SOffset = DAG.getIntPtrConstant(VA.getLocMemOffset(), dl);
316 SDValue PtrOff = DAG.getNode(
317 ISD::ADD, dl, getPointerTy(DAG.getDataLayout()), StackPtr, SOffset);
318
319 SDValue Store =
320 DAG.getStore(Chain, dl, Arg, PtrOff, MachinePointerInfo());
321 MemOpChains.push_back(Store);
322 IsTailCall = false;
323 }
324 }
325
326 // Transform all store nodes into one single node because
327 // all store nodes are independent of each other.
328 if (!MemOpChains.empty())
329 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOpChains);
330
331 // Build a sequence of copy-to-reg nodes chained together with token
332 // chain and flag operands which copy the outgoing args into registers.
333 // The Glue in necessary since all emitted instructions must be
334 // stuck together.
335 SDValue Glue;
336 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
337 Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first,
338 RegsToPass[i].second, Glue);
339 Glue = Chain.getValue(1);
340 }
341
342 // If the callee is a GlobalAddress node (quite common, every direct call is)
343 // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
344 // Likewise ExternalSymbol -> TargetExternalSymbol.
345 bool IsDirect = true;
346 if (auto *G = dyn_cast<GlobalAddressSDNode>(Callee))
347 Callee = DAG.getTargetGlobalAddress(G->getGlobal(), dl, MVT::i32);
348 else if (auto *E = dyn_cast<ExternalSymbolSDNode>(Callee))
349 Callee = DAG.getTargetExternalSymbol(E->getSymbol(), MVT::i32);
350 else
351 IsDirect = false;
352 // Branch + Link = #chain, #target_address, #opt_in_flags...
353 // = Chain, Callee, Reg#1, Reg#2, ...
354 //
355 // Returns a chain & a glue for retval copy to use.
356 SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
358 Ops.push_back(Chain);
359 Ops.push_back(Callee);
360
361 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
362 Ops.push_back(DAG.getRegister(RegsToPass[i].first,
363 RegsToPass[i].second.getValueType()));
364
365 // Add a register mask operand representing the call-preserved registers.
366 const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
367 const uint32_t *Mask =
368 TRI->getCallPreservedMask(DAG.getMachineFunction(), CallConv);
369 assert(Mask && "Missing call preserved mask for calling convention");
370 Ops.push_back(DAG.getRegisterMask(Mask));
371
372 if (Glue.getNode())
373 Ops.push_back(Glue);
374
375 Chain = DAG.getNode(IsDirect ? ARCISD::BL : ARCISD::JL, dl, NodeTys, Ops);
376 Glue = Chain.getValue(1);
377
378 // Create the CALLSEQ_END node.
379 Chain = DAG.getCALLSEQ_END(Chain, NumBytes, 0, Glue, dl);
380 Glue = Chain.getValue(1);
381
382 // Handle result values, copying them out of physregs into vregs that we
383 // return.
384 if (IsTailCall)
385 return Chain;
386 return lowerCallResult(Chain, Glue, RVLocs, dl, DAG, InVals);
387}
388
389/// Lower the result values of a call into the appropriate copies out of
390/// physical registers / memory locations.
392 const SmallVectorImpl<CCValAssign> &RVLocs,
393 SDLoc dl, SelectionDAG &DAG,
394 SmallVectorImpl<SDValue> &InVals) {
395 SmallVector<std::pair<int, unsigned>, 4> ResultMemLocs;
396 // Copy results out of physical registers.
397 for (unsigned i = 0, e = RVLocs.size(); i != e; ++i) {
398 const CCValAssign &VA = RVLocs[i];
399 if (VA.isRegLoc()) {
400 SDValue RetValue;
401 RetValue =
402 DAG.getCopyFromReg(Chain, dl, VA.getLocReg(), VA.getValVT(), Glue);
403 Chain = RetValue.getValue(1);
404 Glue = RetValue.getValue(2);
405 InVals.push_back(RetValue);
406 } else {
407 assert(VA.isMemLoc() && "Must be memory location.");
408 ResultMemLocs.push_back(
409 std::make_pair(VA.getLocMemOffset(), InVals.size()));
410
411 // Reserve space for this result.
412 InVals.push_back(SDValue());
413 }
414 }
415
416 // Copy results out of memory.
417 SmallVector<SDValue, 4> MemOpChains;
418 for (unsigned i = 0, e = ResultMemLocs.size(); i != e; ++i) {
419 int Offset = ResultMemLocs[i].first;
420 unsigned Index = ResultMemLocs[i].second;
421 SDValue StackPtr = DAG.getRegister(ARC::SP, MVT::i32);
422 SDValue SpLoc = DAG.getNode(ISD::ADD, dl, MVT::i32, StackPtr,
423 DAG.getConstant(Offset, dl, MVT::i32));
424 SDValue Load =
425 DAG.getLoad(MVT::i32, dl, Chain, SpLoc, MachinePointerInfo());
426 InVals[Index] = Load;
427 MemOpChains.push_back(Load.getValue(1));
428 }
429
430 // Transform all loads nodes into one single node because
431 // all load nodes are independent of each other.
432 if (!MemOpChains.empty())
433 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOpChains);
434
435 return Chain;
436}
437
438//===----------------------------------------------------------------------===//
439// Formal Arguments Calling Convention Implementation
440//===----------------------------------------------------------------------===//
441
442namespace {
443
444struct ArgDataPair {
445 SDValue SDV;
447};
448
449} // end anonymous namespace
450
451/// ARC formal arguments implementation
452SDValue ARCTargetLowering::LowerFormalArguments(
453 SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
454 const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl,
455 SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals) const {
456 switch (CallConv) {
457 default:
458 llvm_unreachable("Unsupported calling convention");
459 case CallingConv::C:
461 return LowerCallArguments(Chain, CallConv, IsVarArg, Ins, dl, DAG, InVals);
462 }
463}
464
465/// Transform physical registers into virtual registers, and generate load
466/// operations for argument places on the stack.
467SDValue ARCTargetLowering::LowerCallArguments(
468 SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
470 SmallVectorImpl<SDValue> &InVals) const {
472 MachineFrameInfo &MFI = MF.getFrameInfo();
474 auto *AFI = MF.getInfo<ARCFunctionInfo>();
475
476 // Assign locations to all of the incoming arguments.
478 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), ArgLocs,
479 *DAG.getContext());
480
481 CCInfo.AnalyzeFormalArguments(Ins, CC_ARC);
482
483 unsigned StackSlotSize = 4;
484
485 if (!IsVarArg)
486 AFI->setReturnStackOffset(CCInfo.getStackSize());
487
488 // All getCopyFromReg ops must precede any getMemcpys to prevent the
489 // scheduler clobbering a register before it has been copied.
490 // The stages are:
491 // 1. CopyFromReg (and load) arg & vararg registers.
492 // 2. Chain CopyFromReg nodes into a TokenFactor.
493 // 3. Memcpy 'byVal' args & push final InVals.
494 // 4. Chain mem ops nodes into a TokenFactor.
495 SmallVector<SDValue, 4> CFRegNode;
498
499 // 1a. CopyFromReg (and load) arg registers.
500 for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
501 CCValAssign &VA = ArgLocs[i];
502 SDValue ArgIn;
503
504 if (VA.isRegLoc()) {
505 // Arguments passed in registers
506 EVT RegVT = VA.getLocVT();
507 switch (RegVT.getSimpleVT().SimpleTy) {
508 default: {
509 LLVM_DEBUG(errs() << "LowerFormalArguments Unhandled argument type: "
510 << (unsigned)RegVT.getSimpleVT().SimpleTy << "\n");
511 llvm_unreachable("Unhandled LowerFormalArguments type.");
512 }
513 case MVT::i32:
514 unsigned VReg = RegInfo.createVirtualRegister(&ARC::GPR32RegClass);
515 RegInfo.addLiveIn(VA.getLocReg(), VReg);
516 ArgIn = DAG.getCopyFromReg(Chain, dl, VReg, RegVT);
517 CFRegNode.push_back(ArgIn.getValue(ArgIn->getNumValues() - 1));
518 }
519 } else {
520 // Only arguments passed on the stack should make it here.
521 assert(VA.isMemLoc());
522 // Load the argument to a virtual register
523 unsigned ObjSize = VA.getLocVT().getStoreSize();
524 assert((ObjSize <= StackSlotSize) && "Unhandled argument");
525
526 // Create the frame index object for this incoming parameter...
527 int FI = MFI.CreateFixedObject(ObjSize, VA.getLocMemOffset(), true);
528
529 // Create the SelectionDAG nodes corresponding to a load
530 // from this parameter
531 SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);
532 ArgIn = DAG.getLoad(VA.getLocVT(), dl, Chain, FIN,
534 }
535 const ArgDataPair ADP = {ArgIn, Ins[i].Flags};
536 ArgData.push_back(ADP);
537 }
538
539 // 1b. CopyFromReg vararg registers.
540 if (IsVarArg) {
541 // Argument registers
542 static const MCPhysReg ArgRegs[] = {ARC::R0, ARC::R1, ARC::R2, ARC::R3,
543 ARC::R4, ARC::R5, ARC::R6, ARC::R7};
544 auto *AFI = MF.getInfo<ARCFunctionInfo>();
545 unsigned FirstVAReg = CCInfo.getFirstUnallocated(ArgRegs);
546 if (FirstVAReg < std::size(ArgRegs)) {
547 int Offset = 0;
548 // Save remaining registers, storing higher register numbers at a higher
549 // address
550 // There are (std::size(ArgRegs) - FirstVAReg) registers which
551 // need to be saved.
552 int VarFI = MFI.CreateFixedObject((std::size(ArgRegs) - FirstVAReg) * 4,
553 CCInfo.getStackSize(), true);
554 AFI->setVarArgsFrameIndex(VarFI);
555 SDValue FIN = DAG.getFrameIndex(VarFI, MVT::i32);
556 for (unsigned i = FirstVAReg; i < std::size(ArgRegs); i++) {
557 // Move argument from phys reg -> virt reg
558 unsigned VReg = RegInfo.createVirtualRegister(&ARC::GPR32RegClass);
559 RegInfo.addLiveIn(ArgRegs[i], VReg);
560 SDValue Val = DAG.getCopyFromReg(Chain, dl, VReg, MVT::i32);
561 CFRegNode.push_back(Val.getValue(Val->getNumValues() - 1));
562 SDValue VAObj = DAG.getNode(ISD::ADD, dl, MVT::i32, FIN,
563 DAG.getConstant(Offset, dl, MVT::i32));
564 // Move argument from virt reg -> stack
565 SDValue Store =
566 DAG.getStore(Val.getValue(1), dl, Val, VAObj, MachinePointerInfo());
567 MemOps.push_back(Store);
568 Offset += 4;
569 }
570 } else {
571 llvm_unreachable("Too many var args parameters.");
572 }
573 }
574
575 // 2. Chain CopyFromReg nodes into a TokenFactor.
576 if (!CFRegNode.empty())
577 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, CFRegNode);
578
579 // 3. Memcpy 'byVal' args & push final InVals.
580 // Aggregates passed "byVal" need to be copied by the callee.
581 // The callee will use a pointer to this copy, rather than the original
582 // pointer.
583 for (const auto &ArgDI : ArgData) {
584 if (ArgDI.Flags.isByVal() && ArgDI.Flags.getByValSize()) {
585 unsigned Size = ArgDI.Flags.getByValSize();
586 Align Alignment =
587 std::max(Align(StackSlotSize), ArgDI.Flags.getNonZeroByValAlign());
588 // Create a new object on the stack and copy the pointee into it.
589 int FI = MFI.CreateStackObject(Size, Alignment, false);
590 SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);
591 InVals.push_back(FIN);
592 MemOps.push_back(DAG.getMemcpy(
593 Chain, dl, FIN, ArgDI.SDV, DAG.getConstant(Size, dl, MVT::i32),
594 Alignment, false, false, /*CI=*/nullptr, false, MachinePointerInfo(),
596 } else {
597 InVals.push_back(ArgDI.SDV);
598 }
599 }
600
601 // 4. Chain mem ops nodes into a TokenFactor.
602 if (!MemOps.empty()) {
603 MemOps.push_back(Chain);
604 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOps);
605 }
606
607 return Chain;
608}
609
610//===----------------------------------------------------------------------===//
611// Return Value Calling Convention Implementation
612//===----------------------------------------------------------------------===//
613
614bool ARCTargetLowering::CanLowerReturn(
615 CallingConv::ID CallConv, MachineFunction &MF, bool IsVarArg,
616 const SmallVectorImpl<ISD::OutputArg> &Outs, LLVMContext &Context,
617 const Type *RetTy) const {
619 CCState CCInfo(CallConv, IsVarArg, MF, RVLocs, Context);
620 if (!CCInfo.CheckReturn(Outs, RetCC_ARC))
621 return false;
622 if (CCInfo.getStackSize() != 0 && IsVarArg)
623 return false;
624 return true;
625}
626
628ARCTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
629 bool IsVarArg,
631 const SmallVectorImpl<SDValue> &OutVals,
632 const SDLoc &dl, SelectionDAG &DAG) const {
633 auto *AFI = DAG.getMachineFunction().getInfo<ARCFunctionInfo>();
635
636 // CCValAssign - represent the assignment of
637 // the return value to a location
639
640 // CCState - Info about the registers and stack slot.
641 CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs,
642 *DAG.getContext());
643
644 // Analyze return values.
645 if (!IsVarArg)
646 CCInfo.AllocateStack(AFI->getReturnStackOffset(), Align(4));
647
648 CCInfo.AnalyzeReturn(Outs, RetCC_ARC);
649
650 SDValue Glue;
651 SmallVector<SDValue, 4> RetOps(1, Chain);
652 SmallVector<SDValue, 4> MemOpChains;
653 // Handle return values that must be copied to memory.
654 for (unsigned i = 0, e = RVLocs.size(); i != e; ++i) {
655 CCValAssign &VA = RVLocs[i];
656 if (VA.isRegLoc())
657 continue;
658 assert(VA.isMemLoc());
659 if (IsVarArg) {
660 report_fatal_error("Can't return value from vararg function in memory");
661 }
662
663 int Offset = VA.getLocMemOffset();
664 unsigned ObjSize = VA.getLocVT().getStoreSize();
665 // Create the frame index object for the memory location.
666 int FI = MFI.CreateFixedObject(ObjSize, Offset, false);
667
668 // Create a SelectionDAG node corresponding to a store
669 // to this memory location.
670 SDValue FIN = DAG.getFrameIndex(FI, MVT::i32);
671 MemOpChains.push_back(DAG.getStore(
672 Chain, dl, OutVals[i], FIN,
674 }
675
676 // Transform all store nodes into one single node because
677 // all stores are independent of each other.
678 if (!MemOpChains.empty())
679 Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOpChains);
680
681 // Now handle return values copied to registers.
682 for (unsigned i = 0, e = RVLocs.size(); i != e; ++i) {
683 CCValAssign &VA = RVLocs[i];
684 if (!VA.isRegLoc())
685 continue;
686 // Copy the result values into the output registers.
687 Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(), OutVals[i], Glue);
688
689 // guarantee that all emitted copies are
690 // stuck together, avoiding something bad
691 Glue = Chain.getValue(1);
692 RetOps.push_back(DAG.getRegister(VA.getLocReg(), VA.getLocVT()));
693 }
694
695 RetOps[0] = Chain; // Update chain.
696
697 // Add the glue if we have it.
698 if (Glue.getNode())
699 RetOps.push_back(Glue);
700
701 // What to do with the RetOps?
702 return DAG.getNode(ARCISD::RET, dl, MVT::Other, RetOps);
703}
704
705//===----------------------------------------------------------------------===//
706// Target Optimization Hooks
707//===----------------------------------------------------------------------===//
708
709SDValue ARCTargetLowering::PerformDAGCombine(SDNode *N,
710 DAGCombinerInfo &DCI) const {
711 return {};
712}
713
714//===----------------------------------------------------------------------===//
715// Addressing mode description hooks
716//===----------------------------------------------------------------------===//
717
718/// Return true if the addressing mode represented by AM is legal for this
719/// target, for a load/store of the specified type.
721 const AddrMode &AM, Type *Ty,
722 unsigned AS,
723 Instruction *I) const {
724 return AM.Scale == 0;
725}
726
727// Don't emit tail calls for the time being.
728bool ARCTargetLowering::mayBeEmittedAsTailCall(const CallInst *CI) const {
729 return false;
730}
731
732SDValue ARCTargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const {
733 const ARCRegisterInfo &ARI = *Subtarget.getRegisterInfo();
735 MachineFrameInfo &MFI = MF.getFrameInfo();
736 MFI.setFrameAddressIsTaken(true);
737
738 EVT VT = Op.getValueType();
739 SDLoc dl(Op);
740 assert(Op.getConstantOperandVal(0) == 0 &&
741 "Only support lowering frame addr of current frame.");
742 Register FrameReg = ARI.getFrameRegister(MF);
743 return DAG.getCopyFromReg(DAG.getEntryNode(), dl, FrameReg, VT);
744}
745
746SDValue ARCTargetLowering::LowerGlobalAddress(SDValue Op,
747 SelectionDAG &DAG) const {
748 const GlobalAddressSDNode *GN = cast<GlobalAddressSDNode>(Op);
749 const GlobalValue *GV = GN->getGlobal();
750 SDLoc dl(GN);
751 int64_t Offset = GN->getOffset();
752 SDValue GA = DAG.getTargetGlobalAddress(GV, dl, MVT::i32, Offset);
753 return DAG.getNode(ARCISD::GAWRAPPER, dl, MVT::i32, GA);
754}
755
758 auto *FuncInfo = MF.getInfo<ARCFunctionInfo>();
759
760 // vastart just stores the address of the VarArgsFrameIndex slot into the
761 // memory location argument.
762 SDLoc dl(Op);
764 SDValue FR = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(), PtrVT);
765 const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
766 return DAG.getStore(Op.getOperand(0), dl, FR, Op.getOperand(1),
768}
769
771 switch (Op.getOpcode()) {
773 return LowerGlobalAddress(Op, DAG);
774 case ISD::FRAMEADDR:
775 return LowerFRAMEADDR(Op, DAG);
776 case ISD::SELECT_CC:
777 return LowerSELECT_CC(Op, DAG);
778 case ISD::BR_CC:
779 return LowerBR_CC(Op, DAG);
781 return LowerSIGN_EXTEND_INREG(Op, DAG);
782 case ISD::JumpTable:
783 return LowerJumpTable(Op, DAG);
784 case ISD::VASTART:
785 return LowerVASTART(Op, DAG);
787 // As of LLVM 3.8, the lowering code insists that we customize it even
788 // though we've declared the i32 version as legal. This is because it only
789 // thinks i64 is the truly supported version. We've already converted the
790 // i64 version to a widened i32.
791 assert(Op.getSimpleValueType() == MVT::i32);
792 return Op;
793 default:
794 llvm_unreachable("unimplemented operand");
795 }
796}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static ARCCC::CondCode ISDCCtoARCCC(ISD::CondCode isdCC)
static SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG)
static SDValue lowerCallResult(SDValue Chain, SDValue InGlue, const SmallVectorImpl< CCValAssign > &RVLocs, SDLoc dl, SelectionDAG &DAG, SmallVectorImpl< SDValue > &InVals)
Lower the result values of a call into the appropriate copies out of physical registers / memory loca...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis Results
return RetTy
uint64_t Size
#define I(x, y, z)
Definition: MD5.cpp:58
#define G(x, y, z)
Definition: MD5.cpp:56
Register const TargetRegisterInfo * TRI
#define LLVM_DEBUG(...)
Definition: Debug.h:119
Value * RHS
Value * LHS
ARCFunctionInfo - This class is derived from MachineFunction private ARC target-specific information ...
const ARCRegisterInfo * getRegisterInfo() const override
Definition: ARCSubtarget.h:59
SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override
Provide custom lowering hooks for some operations.
bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, unsigned AS, Instruction *I=nullptr) const override
Return true if the addressing mode represented by AM is legal for this target, for a load/store of th...
ARCTargetLowering(const TargetMachine &TM, const ARCSubtarget &Subtarget)
CCState - This class holds information needed while lowering arguments and return values.
CCValAssign - Represent assignment of one arg/retval to a location.
bool isRegLoc() const
Register getLocReg() const
LocInfo getLocInfo() const
bool isMemLoc() const
int64_t getLocMemOffset() const
This class represents a function call, abstracting a target machine's calling convention.
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
Definition: DataLayout.h:63
const GlobalValue * getGlobal() const
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:68
SimpleValueType SimpleTy
TypeSize getStoreSize() const
Return the number of bytes overwritten by a store of the specified value type.
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.
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)
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
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.
unsigned getNumValues() const
Return the number of values defined/returned by this operator.
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...
Definition: SelectionDAG.h:229
SDValue getTargetGlobalAddress(const GlobalValue *GV, const SDLoc &DL, EVT VT, int64_t offset=0, unsigned TargetFlags=0)
Definition: SelectionDAG.h:758
SDValue getCopyToReg(SDValue Chain, const SDLoc &dl, Register Reg, SDValue N)
Definition: SelectionDAG.h:813
LLVM_ABI SDVTList getVTList(EVT VT)
Return an SDVTList that represents the list of values specified.
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,...
LLVM_ABI 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(), BatchAAResults *BatchAA=nullptr)
const TargetLowering & getTargetLoweringInfo() const
Definition: SelectionDAG.h:504
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned TargetFlags=0)
Definition: SelectionDAG.h:768
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:839
const DataLayout & getDataLayout() const
Definition: SelectionDAG.h:498
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 getIntPtrConstant(uint64_t Val, const SDLoc &DL, bool isTarget=false)
LLVM_ABI SDValue getNode(unsigned Opcode, const SDLoc &DL, EVT VT, ArrayRef< SDUse > Ops)
Gets or creates the specified node.
MachineFunction & getMachineFunction() const
Definition: SelectionDAG.h:493
LLVM_ABI SDValue getFrameIndex(int FI, EVT VT, bool isTarget=false)
LLVM_ABI SDValue getRegisterMask(const uint32_t *RegMask)
LLVMContext * getContext() const
Definition: SelectionDAG.h:511
LLVM_ABI SDValue getTargetExternalSymbol(const char *Sym, EVT VT, unsigned TargetFlags=0)
SDValue getEntryNode() const
Return the token chain corresponding to the entry of the function.
Definition: SelectionDAG.h:581
bool empty() const
Definition: SmallVector.h:82
size_t size() const
Definition: SmallVector.h:79
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:574
void push_back(const T &Elt)
Definition: SmallVector.h:414
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
void setBooleanVectorContents(BooleanContent Ty)
Specify how the target extends the result of a vector boolean value from a vector of i1 to a wider ty...
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...
void setMaxAtomicSizeInBitsSupported(unsigned SizeInBits)
Set the maximum atomic operation size supported by the backend.
void setBooleanContents(BooleanContent Ty)
Specify how the target extends the result of integer and floating point boolean values from i1 to a w...
void computeRegisterProperties(const TargetRegisterInfo *TRI)
Once all of the register classes are added, this allows us to compute derived properties we expose.
void addRegisterClass(MVT VT, const TargetRegisterClass *RC)
Add the specified register class as an available regclass for the specified value type.
bool isTypeLegal(EVT VT) const
Return true if the target has native support 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 setStackPointerRegisterToSaveRestore(Register R)
If set to a physical register, this specifies the register that llvm.savestack/llvm....
void setSchedulingPreference(Sched::Preference Pref)
Specify the target scheduling preference.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:83
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:45
LLVM Value Representation.
Definition: Value.h:75
#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:126
@ 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
@ STACKRESTORE
STACKRESTORE has two operands, an input chain and a pointer to restore to it returns an output chain.
Definition: ISDOpcodes.h:1236
@ STACKSAVE
STACKSAVE - STACKSAVE has one operand, an input chain.
Definition: ISDOpcodes.h:1232
@ VAEND
VAEND, VASTART - VAEND and VASTART have three operands: an input chain, pointer, and a SRCVALUE.
Definition: ISDOpcodes.h:1265
@ ADDC
Carry-setting nodes for multiple precision addition and subtraction.
Definition: ISDOpcodes.h:289
@ ADD
Simple integer binary arithmetic operators.
Definition: ISDOpcodes.h:259
@ LOAD
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
Definition: ISDOpcodes.h:1141
@ ANY_EXTEND
ANY_EXTEND - Used for integer types. The high bits are undefined.
Definition: ISDOpcodes.h:835
@ GlobalAddress
Definition: ISDOpcodes.h:88
@ BUILTIN_OP_END
BUILTIN_OP_END - This must be the last enum value in this list.
Definition: ISDOpcodes.h:1574
@ SIGN_EXTEND
Conversion operators.
Definition: ISDOpcodes.h:826
@ BR_CC
BR_CC - Conditional branch.
Definition: ISDOpcodes.h:1187
@ BR_JT
BR_JT - Jumptable branch.
Definition: ISDOpcodes.h:1166
@ UNDEF
UNDEF - An undefined node.
Definition: ISDOpcodes.h:228
@ VACOPY
VACOPY - VACOPY has 5 operands: an input chain, a destination pointer, a source pointer,...
Definition: ISDOpcodes.h:1261
@ MULHU
MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing an unsigned/signed value of...
Definition: ISDOpcodes.h:695
@ SHL
Shift and rotation operations.
Definition: ISDOpcodes.h:756
@ ZERO_EXTEND
ZERO_EXTEND - Used for integer types, zeroing the new bits.
Definition: ISDOpcodes.h:832
@ SELECT_CC
Select with condition operator - This selects between a true value and a false value (ops #2 and #3) ...
Definition: ISDOpcodes.h:793
@ SIGN_EXTEND_INREG
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
Definition: ISDOpcodes.h:870
@ SMIN
[US]{MIN/MAX} - Binary minimum or maximum of signed or unsigned integers.
Definition: ISDOpcodes.h:718
@ FRAMEADDR
FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and llvm.returnaddress on the DAG.
Definition: ISDOpcodes.h:110
@ READCYCLECOUNTER
READCYCLECOUNTER - This corresponds to the readcyclecounter intrinsic.
Definition: ISDOpcodes.h:1292
@ AND
Bitwise operators - logical and, logical or, logical xor.
Definition: ISDOpcodes.h:730
@ ADDE
Carry-using nodes for multiple precision addition and subtraction.
Definition: ISDOpcodes.h:299
@ TokenFactor
TokenFactor - This node takes multiple tokens as input and produces a single token result.
Definition: ISDOpcodes.h:53
@ VAARG
VAARG - VAARG has four operands: an input chain, a pointer, a SRCVALUE, and the alignment.
Definition: ISDOpcodes.h:1256
@ BRCOND
BRCOND - Conditional branch.
Definition: ISDOpcodes.h:1180
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out,...
Definition: ISDOpcodes.h:1691
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:477
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:207
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition: Error.cpp:167
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
DWARFExpression::Operation Op
#define N
Register getFrameRegister(const MachineFunction &MF) const override
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
MVT getSimpleVT() const
Return the SimpleValueType held in the specified simple EVT.
Definition: ValueTypes.h:311
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 represents a list of ValueType's that has been intern'd by a SelectionDAG.
This represents an addressing mode of: BaseGV + BaseOffs + BaseReg + Scale*ScaleReg + ScalableOffset*...
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