[WebAssembly] Fix hasAddr64 being used before being initializer.

This reverts r248388 and fixes the underlying bug: hasAddr64 was initialized
in runOnMachineFunction, but runOnMachineFunction isn't ever called in
CodeGen/WebAssembly/global.ll since that testcase has no functions. The fix
here is to use AsmPrinter's getPointerSize() as needed to determine the
pointer size instead.

llvm-svn: 248394
This commit is contained in:
Dan Gohman 2015-09-23 16:59:10 +00:00
parent 2812aa82d0
commit 979840d31f
1 changed files with 36 additions and 20 deletions

View File

@ -40,12 +40,11 @@ using namespace llvm;
namespace { namespace {
class WebAssemblyAsmPrinter final : public AsmPrinter { class WebAssemblyAsmPrinter final : public AsmPrinter {
bool hasAddr64;
const WebAssemblyInstrInfo *TII; const WebAssemblyInstrInfo *TII;
public: public:
WebAssemblyAsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer) WebAssemblyAsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer)
: AsmPrinter(TM, std::move(Streamer)), hasAddr64(false), TII(nullptr) {} : AsmPrinter(TM, std::move(Streamer)), TII(nullptr) {}
private: private:
const char *getPassName() const override { const char *getPassName() const override {
@ -62,7 +61,6 @@ private:
bool runOnMachineFunction(MachineFunction &MF) override { bool runOnMachineFunction(MachineFunction &MF) override {
const auto &Subtarget = MF.getSubtarget<WebAssemblySubtarget>(); const auto &Subtarget = MF.getSubtarget<WebAssemblySubtarget>();
hasAddr64 = Subtarget.hasAddr64();
TII = Subtarget.getInstrInfo(); TII = Subtarget.getInstrInfo();
return AsmPrinter::runOnMachineFunction(MF); return AsmPrinter::runOnMachineFunction(MF);
} }
@ -80,6 +78,9 @@ private:
void EmitFunctionBodyEnd() override; void EmitFunctionBodyEnd() override;
void EmitInstruction(const MachineInstr *MI) override; void EmitInstruction(const MachineInstr *MI) override;
static std::string toString(const APFloat &APF);
const char *toString(Type *Ty) const;
}; };
} // end anonymous namespace } // end anonymous namespace
@ -101,7 +102,7 @@ static SmallString<32> OpcodeName(const WebAssemblyInstrInfo *TII,
static std::string toSymbol(StringRef S) { return ("$" + S).str(); } static std::string toSymbol(StringRef S) { return ("$" + S).str(); }
static std::string toString(const APFloat &FP) { std::string WebAssemblyAsmPrinter::toString(const APFloat &FP) {
static const size_t BufBytes = 128; static const size_t BufBytes = 128;
char buf[BufBytes]; char buf[BufBytes];
if (FP.isNaN()) if (FP.isNaN())
@ -118,20 +119,37 @@ static std::string toString(const APFloat &FP) {
return buf; return buf;
} }
static const char *toString(const Type *Ty, bool hasAddr64) { const char *WebAssemblyAsmPrinter::toString(Type *Ty) const {
switch (Ty->getTypeID()) { switch (Ty->getTypeID()) {
default: break; default:
break;
// Treat all pointers as the underlying integer into linear memory. // Treat all pointers as the underlying integer into linear memory.
case Type::PointerTyID: return hasAddr64 ? "i64" : "i32"; case Type::PointerTyID:
case Type::FloatTyID: return "f32"; switch (getPointerSize()) {
case Type::DoubleTyID: return "f64"; case 4:
return "i32";
case 8:
return "i64";
default:
llvm_unreachable("unsupported pointer size");
}
break;
case Type::FloatTyID:
return "f32";
case Type::DoubleTyID:
return "f64";
case Type::IntegerTyID: case Type::IntegerTyID:
switch (Ty->getIntegerBitWidth()) { switch (Ty->getIntegerBitWidth()) {
case 8: return "i8"; case 8:
case 16: return "i16"; return "i8";
case 32: return "i32"; case 16:
case 64: return "i64"; return "i16";
default: break; case 32:
return "i32";
case 64:
return "i64";
default:
break;
} }
} }
DEBUG(dbgs() << "Invalid type "; Ty->print(dbgs()); dbgs() << '\n'); DEBUG(dbgs() << "Invalid type "; Ty->print(dbgs()); dbgs() << '\n');
@ -139,7 +157,6 @@ static const char *toString(const Type *Ty, bool hasAddr64) {
return "<invalid>"; return "<invalid>";
} }
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// WebAssemblyAsmPrinter Implementation. // WebAssemblyAsmPrinter Implementation.
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -195,8 +212,7 @@ void WebAssemblyAsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
return; return;
} }
OS << "(global " << toSymbol(Name) << ' ' OS << "(global " << toSymbol(Name) << ' ' << toString(Init->getType()) << ' ';
<< toString(Init->getType(), hasAddr64) << ' ';
if (const auto *C = dyn_cast<ConstantInt>(Init)) { if (const auto *C = dyn_cast<ConstantInt>(Init)) {
assert(C->getBitWidth() <= 64 && "Printing wider types unimplemented"); assert(C->getBitWidth() <= 64 && "Printing wider types unimplemented");
OS << C->getZExtValue(); OS << C->getZExtValue();
@ -241,12 +257,12 @@ void WebAssemblyAsmPrinter::EmitFunctionBodyStart() {
SmallString<128> Str; SmallString<128> Str;
raw_svector_ostream OS(Str); raw_svector_ostream OS(Str);
const Function *F = MF->getFunction(); const Function *F = MF->getFunction();
const Type *Rt = F->getReturnType(); Type *Rt = F->getReturnType();
if (!Rt->isVoidTy() || !F->arg_empty()) { if (!Rt->isVoidTy() || !F->arg_empty()) {
for (const Argument &A : F->args()) for (const Argument &A : F->args())
OS << " (param " << toString(A.getType(), hasAddr64) << ')'; OS << " (param " << toString(A.getType()) << ')';
if (!Rt->isVoidTy()) if (!Rt->isVoidTy())
OS << " (result " << toString(Rt, hasAddr64) << ')'; OS << " (result " << toString(Rt) << ')';
OutStreamer->EmitRawText(OS.str()); OutStreamer->EmitRawText(OS.str());
} }
} }