mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
[WebAssembly] Fix function return type printing
Summary: Previously return type information for a function was derived from return dag nodes. But this didn't work for dags with != return node. So instead compute it directly from the LLVM function as is done for imports. Differential Revision: http://reviews.llvm.org/D14593 llvm-svn: 253251
This commit is contained in:
parent
bd98758dfe
commit
a288942d7d
@ -146,14 +146,38 @@ void WebAssemblyAsmPrinter::EmitJumpTableInfo() {
|
|||||||
// Nothing to do; jump tables are incorporated into the instruction stream.
|
// Nothing to do; jump tables are incorporated into the instruction stream.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ComputeLegalValueVTs(const Function &F,
|
||||||
|
const TargetMachine &TM,
|
||||||
|
Type *Ty,
|
||||||
|
SmallVectorImpl<MVT> &ValueVTs) {
|
||||||
|
const DataLayout& DL(F.getParent()->getDataLayout());
|
||||||
|
const WebAssemblyTargetLowering &TLI =
|
||||||
|
*TM.getSubtarget<WebAssemblySubtarget>(F).getTargetLowering();
|
||||||
|
SmallVector<EVT, 4> VTs;
|
||||||
|
ComputeValueVTs(TLI, DL, Ty, VTs);
|
||||||
|
|
||||||
|
for (EVT VT : VTs) {
|
||||||
|
unsigned NumRegs = TLI.getNumRegisters(F.getContext(), VT);
|
||||||
|
MVT RegisterVT = TLI.getRegisterType(F.getContext(), VT);
|
||||||
|
for (unsigned i = 0; i != NumRegs; ++i)
|
||||||
|
ValueVTs.push_back(RegisterVT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void WebAssemblyAsmPrinter::EmitFunctionBodyStart() {
|
void WebAssemblyAsmPrinter::EmitFunctionBodyStart() {
|
||||||
SmallString<128> Str;
|
SmallString<128> Str;
|
||||||
raw_svector_ostream OS(Str);
|
raw_svector_ostream OS(Str);
|
||||||
|
|
||||||
for (MVT VT : MFI->getParams())
|
for (MVT VT : MFI->getParams())
|
||||||
OS << "\t" ".param " << toString(VT) << '\n';
|
OS << "\t" ".param " << toString(VT) << '\n';
|
||||||
for (MVT VT : MFI->getResults())
|
|
||||||
OS << "\t" ".result " << toString(VT) << '\n';
|
SmallVector<MVT, 4> ResultVTs;
|
||||||
|
const Function &F(*MF->getFunction());
|
||||||
|
ComputeLegalValueVTs(F, TM, F.getReturnType(), ResultVTs);
|
||||||
|
// If the return type needs to be legalized it will get converted into
|
||||||
|
// passing a pointer.
|
||||||
|
if (ResultVTs.size() == 1)
|
||||||
|
OS << "\t" ".result " << toString(ResultVTs.front()) << '\n';
|
||||||
|
|
||||||
bool FirstVReg = true;
|
bool FirstVReg = true;
|
||||||
for (unsigned Idx = 0, IdxE = MRI->getNumVirtRegs(); Idx != IdxE; ++Idx) {
|
for (unsigned Idx = 0, IdxE = MRI->getNumVirtRegs(); Idx != IdxE; ++Idx) {
|
||||||
@ -210,20 +234,7 @@ void WebAssemblyAsmPrinter::EmitInstruction(const MachineInstr *MI) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ComputeLegalValueVTs(LLVMContext &Context,
|
|
||||||
const WebAssemblyTargetLowering &TLI,
|
|
||||||
const DataLayout &DL, Type *Ty,
|
|
||||||
SmallVectorImpl<MVT> &ValueVTs) {
|
|
||||||
SmallVector<EVT, 4> VTs;
|
|
||||||
ComputeValueVTs(TLI, DL, Ty, VTs);
|
|
||||||
|
|
||||||
for (EVT VT : VTs) {
|
|
||||||
unsigned NumRegs = TLI.getNumRegisters(Context, VT);
|
|
||||||
MVT RegisterVT = TLI.getRegisterType(Context, VT);
|
|
||||||
for (unsigned i = 0; i != NumRegs; ++i)
|
|
||||||
ValueVTs.push_back(RegisterVT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void WebAssemblyAsmPrinter::EmitEndOfAsmFile(Module &M) {
|
void WebAssemblyAsmPrinter::EmitEndOfAsmFile(Module &M) {
|
||||||
const DataLayout &DL = M.getDataLayout();
|
const DataLayout &DL = M.getDataLayout();
|
||||||
@ -248,8 +259,7 @@ void WebAssemblyAsmPrinter::EmitEndOfAsmFile(Module &M) {
|
|||||||
// passing a pointer.
|
// passing a pointer.
|
||||||
bool SawParam = false;
|
bool SawParam = false;
|
||||||
SmallVector<MVT, 4> ResultVTs;
|
SmallVector<MVT, 4> ResultVTs;
|
||||||
ComputeLegalValueVTs(M.getContext(), TLI, DL, F.getReturnType(),
|
ComputeLegalValueVTs(F, TM, F.getReturnType(), ResultVTs);
|
||||||
ResultVTs);
|
|
||||||
if (ResultVTs.size() > 1) {
|
if (ResultVTs.size() > 1) {
|
||||||
ResultVTs.clear();
|
ResultVTs.clear();
|
||||||
OS << " (param " << toString(TLI.getPointerTy(DL));
|
OS << " (param " << toString(TLI.getPointerTy(DL));
|
||||||
@ -258,20 +268,20 @@ void WebAssemblyAsmPrinter::EmitEndOfAsmFile(Module &M) {
|
|||||||
|
|
||||||
for (const Argument &A : F.args()) {
|
for (const Argument &A : F.args()) {
|
||||||
SmallVector<MVT, 4> ParamVTs;
|
SmallVector<MVT, 4> ParamVTs;
|
||||||
ComputeLegalValueVTs(M.getContext(), TLI, DL, A.getType(), ParamVTs);
|
ComputeLegalValueVTs(F, TM, A.getType(), ParamVTs);
|
||||||
for (EVT VT : ParamVTs) {
|
for (MVT VT : ParamVTs) {
|
||||||
if (!SawParam) {
|
if (!SawParam) {
|
||||||
OS << " (param";
|
OS << " (param";
|
||||||
SawParam = true;
|
SawParam = true;
|
||||||
}
|
}
|
||||||
OS << ' ' << toString(VT.getSimpleVT());
|
OS << ' ' << toString(VT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (SawParam)
|
if (SawParam)
|
||||||
OS << ')';
|
OS << ')';
|
||||||
|
|
||||||
for (EVT VT : ResultVTs)
|
for (MVT VT : ResultVTs)
|
||||||
OS << " (result " << toString(VT.getSimpleVT()) << ')';
|
OS << " (result " << toString(VT) << ')';
|
||||||
|
|
||||||
OS << '\n';
|
OS << '\n';
|
||||||
}
|
}
|
||||||
|
@ -326,8 +326,6 @@ SDValue WebAssemblyTargetLowering::LowerReturn(
|
|||||||
const SmallVectorImpl<ISD::OutputArg> &Outs,
|
const SmallVectorImpl<ISD::OutputArg> &Outs,
|
||||||
const SmallVectorImpl<SDValue> &OutVals, SDLoc DL,
|
const SmallVectorImpl<SDValue> &OutVals, SDLoc DL,
|
||||||
SelectionDAG &DAG) const {
|
SelectionDAG &DAG) const {
|
||||||
MachineFunction &MF = DAG.getMachineFunction();
|
|
||||||
|
|
||||||
assert(Outs.size() <= 1 && "WebAssembly can only return up to one value");
|
assert(Outs.size() <= 1 && "WebAssembly can only return up to one value");
|
||||||
if (CallConv != CallingConv::C)
|
if (CallConv != CallingConv::C)
|
||||||
fail(DL, DAG, "WebAssembly doesn't support non-C calling conventions");
|
fail(DL, DAG, "WebAssembly doesn't support non-C calling conventions");
|
||||||
@ -352,7 +350,6 @@ SDValue WebAssemblyTargetLowering::LowerReturn(
|
|||||||
fail(DL, DAG, "WebAssembly hasn't implemented cons regs last results");
|
fail(DL, DAG, "WebAssembly hasn't implemented cons regs last results");
|
||||||
if (!Out.IsFixed)
|
if (!Out.IsFixed)
|
||||||
fail(DL, DAG, "WebAssembly doesn't support non-fixed results yet");
|
fail(DL, DAG, "WebAssembly doesn't support non-fixed results yet");
|
||||||
MF.getInfo<WebAssemblyFunctionInfo>()->addResult(Out.VT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Chain;
|
return Chain;
|
||||||
|
@ -28,7 +28,6 @@ class WebAssemblyFunctionInfo final : public MachineFunctionInfo {
|
|||||||
MachineFunction &MF;
|
MachineFunction &MF;
|
||||||
|
|
||||||
std::vector<MVT> Params;
|
std::vector<MVT> Params;
|
||||||
std::vector<MVT> Results;
|
|
||||||
|
|
||||||
/// A mapping from CodeGen vreg index to WebAssembly register number.
|
/// A mapping from CodeGen vreg index to WebAssembly register number.
|
||||||
std::vector<unsigned> WARegs;
|
std::vector<unsigned> WARegs;
|
||||||
@ -48,9 +47,6 @@ public:
|
|||||||
void addParam(MVT VT) { Params.push_back(VT); }
|
void addParam(MVT VT) { Params.push_back(VT); }
|
||||||
const std::vector<MVT> &getParams() const { return Params; }
|
const std::vector<MVT> &getParams() const { return Params; }
|
||||||
|
|
||||||
void addResult(MVT VT) { Results.push_back(VT); }
|
|
||||||
const std::vector<MVT> &getResults() const { return Results; }
|
|
||||||
|
|
||||||
static const unsigned UnusedReg = -1u;
|
static const unsigned UnusedReg = -1u;
|
||||||
|
|
||||||
void stackifyVReg(unsigned VReg) {
|
void stackifyVReg(unsigned VReg) {
|
||||||
|
@ -45,3 +45,24 @@ define i32 @f2(i32 %p1, float %p2) {
|
|||||||
define void @f3(i32 %p1, float %p2) {
|
define void @f3(i32 %p1, float %p2) {
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
|
|
||||||
|
; CHECK-LABEL: f4:
|
||||||
|
; CHECK-NEXT: .param i32{{$}}
|
||||||
|
; CHECK-NEXT: .result i32{{$}}
|
||||||
|
; CHECK-NEXT: .local
|
||||||
|
define i32 @f4(i32 %x) {
|
||||||
|
entry:
|
||||||
|
%c = trunc i32 %x to i1
|
||||||
|
br i1 %c, label %true, label %false
|
||||||
|
true:
|
||||||
|
ret i32 0
|
||||||
|
false:
|
||||||
|
ret i32 1
|
||||||
|
}
|
||||||
|
|
||||||
|
; CHECK-LABEL: f5:
|
||||||
|
; CHECK-NEXT: .result f32{{$}}
|
||||||
|
; CHECK-NEXT: unreachable
|
||||||
|
define float @f5() {
|
||||||
|
unreachable
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user