summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r--llvm/lib/CodeGen/GlobalISel/CallLowering.cpp71
-rw-r--r--llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp7
-rw-r--r--llvm/lib/CodeGen/LowLevelType.cpp18
3 files changed, 89 insertions, 7 deletions
diff --git a/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp b/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp
index de63280fd71..578556cc8bb 100644
--- a/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/CallLowering.cpp
@@ -16,18 +16,28 @@
#include "llvm/CodeGen/GlobalISel/CallLowering.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/IR/Instructions.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Target/TargetLowering.h"
using namespace llvm;
bool CallLowering::lowerCall(
MachineIRBuilder &MIRBuilder, const CallInst &CI, unsigned ResReg,
ArrayRef<unsigned> ArgRegs, std::function<unsigned()> GetCalleeReg) const {
+ auto &DL = CI.getParent()->getParent()->getParent()->getDataLayout();
+
// First step is to marshall all the function's parameters into the correct
// physregs and memory locations. Gather the sequence of argument types that
// we'll pass to the assigner function.
- SmallVector<Type *, 8> ArgTys;
- for (auto &Arg : CI.arg_operands())
- ArgTys.push_back(Arg->getType());
+ SmallVector<ArgInfo, 8> OrigArgs;
+ unsigned i = 0;
+ for (auto &Arg : CI.arg_operands()) {
+ ArgInfo OrigArg{ArgRegs[i], Arg->getType(), ISD::ArgFlagsTy{}};
+ setArgFlags(OrigArg, i + 1, DL, CI);
+ OrigArgs.push_back(OrigArg);
+ ++i;
+ }
MachineOperand Callee = MachineOperand::CreateImm(0);
if (Function *F = CI.getCalledFunction())
@@ -35,5 +45,58 @@ bool CallLowering::lowerCall(
else
Callee = MachineOperand::CreateReg(GetCalleeReg(), false);
- return lowerCall(MIRBuilder, Callee, CI.getType(), ResReg, ArgTys, ArgRegs);
+ ArgInfo OrigRet{ResReg, CI.getType(), ISD::ArgFlagsTy{}};
+ if (!OrigRet.Ty->isVoidTy())
+ setArgFlags(OrigRet, AttributeSet::ReturnIndex, DL, CI);
+
+ return lowerCall(MIRBuilder, Callee, OrigRet, OrigArgs);
}
+
+template <typename FuncInfoTy>
+void CallLowering::setArgFlags(CallLowering::ArgInfo &Arg, unsigned OpIdx,
+ const DataLayout &DL,
+ const FuncInfoTy &FuncInfo) const {
+ const AttributeSet &Attrs = FuncInfo.getAttributes();
+ if (Attrs.hasAttribute(OpIdx, Attribute::ZExt))
+ Arg.Flags.setZExt();
+ if (Attrs.hasAttribute(OpIdx, Attribute::SExt))
+ Arg.Flags.setSExt();
+ if (Attrs.hasAttribute(OpIdx, Attribute::InReg))
+ Arg.Flags.setInReg();
+ if (Attrs.hasAttribute(OpIdx, Attribute::StructRet))
+ Arg.Flags.setSRet();
+ if (Attrs.hasAttribute(OpIdx, Attribute::SwiftSelf))
+ Arg.Flags.setSwiftSelf();
+ if (Attrs.hasAttribute(OpIdx, Attribute::SwiftError))
+ Arg.Flags.setSwiftError();
+ if (Attrs.hasAttribute(OpIdx, Attribute::ByVal))
+ Arg.Flags.setByVal();
+ if (Attrs.hasAttribute(OpIdx, Attribute::InAlloca))
+ Arg.Flags.setInAlloca();
+
+ if (Arg.Flags.isByVal() || Arg.Flags.isInAlloca()) {
+ Type *ElementTy = cast<PointerType>(Arg.Ty)->getElementType();
+ Arg.Flags.setByValSize(DL.getTypeAllocSize(ElementTy));
+ // For ByVal, alignment should be passed from FE. BE will guess if
+ // this info is not there but there are cases it cannot get right.
+ unsigned FrameAlign;
+ if (FuncInfo.getParamAlignment(OpIdx))
+ FrameAlign = FuncInfo.getParamAlignment(OpIdx);
+ else
+ FrameAlign = getTLI()->getByValTypeAlignment(ElementTy, DL);
+ Arg.Flags.setByValAlign(FrameAlign);
+ }
+ if (Attrs.hasAttribute(OpIdx, Attribute::Nest))
+ Arg.Flags.setNest();
+ Arg.Flags.setOrigAlign(DL.getABITypeAlignment(Arg.Ty));
+}
+
+template void
+CallLowering::setArgFlags<Function>(CallLowering::ArgInfo &Arg, unsigned OpIdx,
+ const DataLayout &DL,
+ const Function &FuncInfo) const;
+
+template void
+CallLowering::setArgFlags<CallInst>(CallLowering::ArgInfo &Arg, unsigned OpIdx,
+ const DataLayout &DL,
+ const CallInst &FuncInfo) const;
diff --git a/llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp b/llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp
index ede2bc23393..d6368b3d969 100644
--- a/llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/MachineLegalizeHelper.cpp
@@ -109,9 +109,10 @@ MachineLegalizeHelper::libcall(MachineInstr &MI) {
const char *Name =
TLI.getLibcallName(Size == 64 ? RTLIB::REM_F64 : RTLIB::REM_F32);
- CLI.lowerCall(MIRBuilder, MachineOperand::CreateES(Name), Ty,
- MI.getOperand(0).getReg(), {Ty, Ty},
- {MI.getOperand(1).getReg(), MI.getOperand(2).getReg()});
+ CLI.lowerCall(
+ MIRBuilder, MachineOperand::CreateES(Name),
+ {MI.getOperand(0).getReg(), Ty},
+ {{MI.getOperand(1).getReg(), Ty}, {MI.getOperand(2).getReg(), Ty}});
MI.eraseFromParent();
return Legalized;
}
diff --git a/llvm/lib/CodeGen/LowLevelType.cpp b/llvm/lib/CodeGen/LowLevelType.cpp
index fd235f2cfd1..d74b7306e0f 100644
--- a/llvm/lib/CodeGen/LowLevelType.cpp
+++ b/llvm/lib/CodeGen/LowLevelType.cpp
@@ -40,6 +40,24 @@ LLT::LLT(Type &Ty, const DataLayout &DL) {
}
}
+LLT::LLT(MVT VT) {
+ if (VT.isVector()) {
+ SizeInBits = VT.getVectorElementType().getSizeInBits();
+ ElementsOrAddrSpace = VT.getVectorNumElements();
+ Kind = ElementsOrAddrSpace == 1 ? Scalar : Vector;
+ } else if (VT.isValid()) {
+ // Aggregates are no different from real scalars as far as GlobalISel is
+ // concerned.
+ Kind = Scalar;
+ SizeInBits = VT.getSizeInBits();
+ ElementsOrAddrSpace = 1;
+ assert(SizeInBits != 0 && "invalid zero-sized type");
+ } else {
+ Kind = Invalid;
+ SizeInBits = ElementsOrAddrSpace = 0;
+ }
+}
+
void LLT::print(raw_ostream &OS) const {
if (isVector())
OS << "<" << ElementsOrAddrSpace << " x s" << SizeInBits << ">";
OpenPOWER on IntegriCloud