summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
diff options
context:
space:
mode:
authorDan Gohman <dan433584@gmail.com>2015-11-11 01:33:02 +0000
committerDan Gohman <dan433584@gmail.com>2015-11-11 01:33:02 +0000
commit754cd11d9019e62a4c6a0aee62159e707f6f51d9 (patch)
tree8431ec606891d373ee34cba87fcb5fdc4a1b6e70 /llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
parentdc9c5df5cdf4af06179f77a4b451369fcc82aef8 (diff)
downloadbcm5719-llvm-754cd11d9019e62a4c6a0aee62159e707f6f51d9.tar.gz
bcm5719-llvm-754cd11d9019e62a4c6a0aee62159e707f6f51d9.zip
[WebAssembly] Support non-legal argument and return types.
llvm-svn: 252687
Diffstat (limited to 'llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp')
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp150
1 files changed, 88 insertions, 62 deletions
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
index 6eb9ae6c526..27095ec51df 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp
@@ -23,6 +23,7 @@
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/CodeGen/Analysis.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineInstr.h"
@@ -66,7 +67,7 @@ private:
const auto &Subtarget = MF.getSubtarget<WebAssemblySubtarget>();
TII = Subtarget.getInstrInfo();
MRI = &MF.getRegInfo();
- NumArgs = MF.getInfo<WebAssemblyFunctionInfo>()->getNumArguments();
+ NumArgs = MF.getInfo<WebAssemblyFunctionInfo>()->getParams().size();
return AsmPrinter::runOnMachineFunction(MF);
}
@@ -82,7 +83,7 @@ private:
std::string getRegTypeName(unsigned RegNo) const;
static std::string toString(const APFloat &APF);
- const char *toString(Type *Ty) const;
+ const char *toString(MVT VT) const;
std::string regToString(const MachineOperand &MO);
std::string argToString(const MachineOperand &MO);
};
@@ -167,40 +168,20 @@ std::string WebAssemblyAsmPrinter::argToString(const MachineOperand &MO) {
return utostr(ArgNo);
}
-const char *WebAssemblyAsmPrinter::toString(Type *Ty) const {
- switch (Ty->getTypeID()) {
+const char *WebAssemblyAsmPrinter::toString(MVT VT) const {
+ switch (VT.SimpleTy) {
default:
break;
- // Treat all pointers as the underlying integer into linear memory.
- case Type::PointerTyID:
- switch (getPointerSize()) {
- case 4:
- return "i32";
- case 8:
- return "i64";
- default:
- llvm_unreachable("unsupported pointer size");
- }
- break;
- case Type::FloatTyID:
+ case MVT::f32:
return "f32";
- case Type::DoubleTyID:
+ case MVT::f64:
return "f64";
- case Type::IntegerTyID:
- switch (Ty->getIntegerBitWidth()) {
- case 8:
- return "i8";
- case 16:
- return "i16";
- case 32:
- return "i32";
- case 64:
- return "i64";
- default:
- break;
- }
+ case MVT::i32:
+ return "i32";
+ case MVT::i64:
+ return "i64";
}
- DEBUG(dbgs() << "Invalid type "; Ty->print(dbgs()); dbgs() << '\n');
+ DEBUG(dbgs() << "Invalid type " << EVT(VT).getEVTString() << '\n');
llvm_unreachable("invalid type");
return "<invalid>";
}
@@ -219,40 +200,37 @@ void WebAssemblyAsmPrinter::EmitJumpTableInfo() {
}
void WebAssemblyAsmPrinter::EmitFunctionBodyStart() {
- const Function *F = MF->getFunction();
- Type *Rt = F->getReturnType();
SmallString<128> Str;
raw_svector_ostream OS(Str);
- bool First = true;
- if (!Rt->isVoidTy() || !F->arg_empty()) {
- for (const Argument &A : F->args()) {
- OS << (First ? "" : "\n") << "\t.param " << toString(A.getType());
- First = false;
- }
- if (!Rt->isVoidTy()) {
- OS << (First ? "" : "\n") << "\t.result " << toString(Rt);
- First = false;
- }
- }
+ for (MVT VT : MF->getInfo<WebAssemblyFunctionInfo>()->getParams())
+ OS << "\t" ".param "
+ << toString(VT) << '\n';
+ for (MVT VT : MF->getInfo<WebAssemblyFunctionInfo>()->getResults())
+ OS << "\t" ".result "
+ << toString(VT) << '\n';
bool FirstVReg = true;
for (unsigned Idx = 0, IdxE = MRI->getNumVirtRegs(); Idx != IdxE; ++Idx) {
unsigned VReg = TargetRegisterInfo::index2VirtReg(Idx);
// FIXME: Don't skip dead virtual registers for now: that would require
// remapping all locals' numbers.
- //if (!MRI->use_empty(VReg)) {
- if (FirstVReg) {
- OS << (First ? "" : "\n") << "\t.local ";
- First = false;
- }
- OS << (FirstVReg ? "" : ", ") << getRegTypeName(VReg);
- FirstVReg = false;
+ // if (!MRI->use_empty(VReg)) {
+ if (FirstVReg)
+ OS << "\t" ".local ";
+ else
+ OS << ", ";
+ OS << getRegTypeName(VReg);
+ FirstVReg = false;
//}
}
+ if (!FirstVReg)
+ OS << '\n';
- if (!First)
- OutStreamer->EmitRawText(OS.str());
+ // EmitRawText appends a newline, so strip off the last newline.
+ StringRef Text = OS.str();
+ if (!Text.empty())
+ OutStreamer->EmitRawText(Text.substr(0, Text.size() - 1));
AsmPrinter::EmitFunctionBodyStart();
}
@@ -334,27 +312,75 @@ 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) {
+ const DataLayout &DL = M.getDataLayout();
+
SmallString<128> Str;
raw_svector_ostream OS(Str);
for (const Function &F : M)
if (F.isDeclarationForLinker()) {
assert(F.hasName() && "imported functions must have a name");
- if (F.getName().startswith("llvm."))
+ if (F.isIntrinsic())
continue;
if (Str.empty())
OS << "\t.imports\n";
- Type *Rt = F.getReturnType();
+
OS << "\t.import " << toSymbol(F.getName()) << " \"\" \"" << F.getName()
- << "\" (param";
- for (const Argument &A : F.args())
- OS << ' ' << toString(A.getType());
- OS << ')';
- if (!Rt->isVoidTy())
- OS << " (result " << toString(Rt) << ')';
+ << "\"";
+
+ const WebAssemblyTargetLowering &TLI =
+ *TM.getSubtarget<WebAssemblySubtarget>(F).getTargetLowering();
+
+ // If we need to legalize the return type, it'll get converted into
+ // passing a pointer.
+ bool SawParam = false;
+ SmallVector<MVT, 4> ResultVTs;
+ ComputeLegalValueVTs(M.getContext(), TLI, DL, F.getReturnType(),
+ ResultVTs);
+ if (ResultVTs.size() > 1) {
+ ResultVTs.clear();
+ OS << " (param " << toString(TLI.getPointerTy(DL));
+ SawParam = true;
+ }
+
+ for (const Argument &A : F.args()) {
+ SmallVector<MVT, 4> ParamVTs;
+ ComputeLegalValueVTs(M.getContext(), TLI, DL, A.getType(), ParamVTs);
+ for (EVT VT : ParamVTs) {
+ if (!SawParam) {
+ OS << " (param";
+ SawParam = true;
+ }
+ OS << ' ' << toString(VT.getSimpleVT());
+ }
+ }
+ if (SawParam)
+ OS << ')';
+
+ for (EVT VT : ResultVTs)
+ OS << " (result " << toString(VT.getSimpleVT()) << ')';
+
OS << '\n';
}
- OutStreamer->EmitRawText(OS.str());
+
+ StringRef Text = OS.str();
+ if (!Text.empty())
+ OutStreamer->EmitRawText(Text.substr(0, Text.size() - 1));
}
// Force static initialization.
OpenPOWER on IntegriCloud