Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(31)

Unified Diff: src/WasmTranslator.cpp

Issue 1938643002: Subzero, WASM: stop writing uninitialized data to .o file. Add timers. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Make sanitizeAddress private. Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« runtime/wasm-runtime.cpp ('K') | « src/IceTimerTree.def ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/WasmTranslator.cpp
diff --git a/src/WasmTranslator.cpp b/src/WasmTranslator.cpp
index 7bc904e02a57671d2070f68f59fec2f6fca30c7e..81a9fcb36c4986fde40e22636106d945db939095 100644
--- a/src/WasmTranslator.cpp
+++ b/src/WasmTranslator.cpp
@@ -276,6 +276,16 @@ public:
auto *Entry = Func->getEntryNode();
assert(Entry);
LOG(out << Node(Entry) << "\n");
+
+ // Load the WasmMemory address to make it available everywhere else in the
+ // function.
+ auto *WasmMemoryPtr =
+ Ctx->getConstantExternSym(Ctx->getGlobalString("WASM_MEMORY"));
+ assert(!WasmMemory);
Jim Stichnoth 2016/05/02 16:04:07 assert(WasmMemory == nullptr);
Eric Holk 2016/05/02 17:42:37 Done.
+ auto *WasmMemoryV = makeVariable(getPointerType());
+ Entry->appendInst(InstLoad::create(Func, WasmMemoryV, WasmMemoryPtr));
+ WasmMemory = WasmMemoryV;
+
return OperandNode(Entry);
}
Node Param(uint32_t Index, wasm::LocalType Type) {
@@ -1162,71 +1172,6 @@ public:
llvm::report_fatal_error("StoreGlobal");
}
- Operand *sanitizeAddress(Operand *Base, uint32_t Offset) {
Eric Holk 2016/04/29 22:37:42 This function is just moved down lower to make it
- SizeT MemSize = Module->module->min_mem_pages * WASM_PAGE_SIZE;
-
- bool ConstZeroBase = false;
-
- // first, add the index and the offset together.
- if (auto *ConstBase = llvm::dyn_cast<ConstantInteger32>(Base)) {
- uint32_t RealOffset = Offset + ConstBase->getValue();
- if (RealOffset >= MemSize) {
- // We've proven this will always be an out of bounds access, so insert
- // an unconditional trap.
- Control()->appendInst(InstUnreachable::create(Func));
- // It doesn't matter what we return here, so return something that will
- // allow the rest of code generation to happen.
- //
- // We might be tempted to just abort translation here, but out of bounds
- // memory access is a runtime trap, not a compile error.
- return Ctx->getConstantZero(getPointerType());
- }
- Base = Ctx->getConstantInt32(RealOffset);
- ConstZeroBase = (0 == RealOffset);
- } else if (0 != Offset) {
- auto *Addr = makeVariable(Ice::getPointerType());
- auto *OffsetConstant = Ctx->getConstantInt32(Offset);
- Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Add,
- Addr, Base, OffsetConstant));
-
- Base = Addr;
- }
-
- // Do the bounds check.
- //
- // TODO (eholk): Add a command line argument to control whether bounds
- // checks are inserted, and maybe add a way to duplicate bounds checks to
- // get a better sense of the overhead.
- if (!llvm::dyn_cast<ConstantInteger32>(Base)) {
- // TODO (eholk): creating a new basic block on every memory access is
- // terrible (see https://goo.gl/Zj7DTr). Try adding a new instruction that
- // encapsulates this "abort if false" pattern.
- auto *CheckPassed = Func->makeNode();
- auto *CheckFailed = getBoundsFailTarget();
-
- auto *Check = makeVariable(IceType_i1);
- Control()->appendInst(InstIcmp::create(Func, InstIcmp::Ult, Check, Base,
- Ctx->getConstantInt32(MemSize)));
- Control()->appendInst(
- InstBr::create(Func, Check, CheckPassed, CheckFailed));
-
- *ControlPtr = OperandNode(CheckPassed);
- }
-
- Ice::Operand *RealAddr = nullptr;
- auto MemBase = Ctx->getConstantSym(0, Ctx->getGlobalString("WASM_MEMORY"));
- if (!ConstZeroBase) {
- auto RealAddrV = Func->makeVariable(Ice::getPointerType());
- Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Add,
- RealAddrV, Base, MemBase));
-
- RealAddr = RealAddrV;
- } else {
- RealAddr = MemBase;
- }
- return RealAddr;
- }
-
Node LoadMem(wasm::LocalType Type, MachineType MemType, Node Index,
uint32_t Offset) {
LOG(out << "LoadMem." << toIceType(MemType) << "(" << Index << "[" << Offset
@@ -1318,6 +1263,8 @@ private:
CfgUnorderedMap<Operand *, InstPhi *> PhiMap;
CfgUnorderedMap<Operand *, CfgNode *> DefNodeMap;
+ Operand *WasmMemory = nullptr;
+
InstPhi *getDefiningInst(Operand *Op) const {
const auto &Iter = PhiMap.find(Op);
if (Iter == PhiMap.end()) {
@@ -1378,6 +1325,76 @@ private:
return IndirectFailTarget;
}
+ Operand *getWasmMemory() {
+ assert(WasmMemory);
Jim Stichnoth 2016/05/02 16:04:07 assert(WasmMemory != nullptr); I think we're pret
Eric Holk 2016/05/02 17:42:37 Done.
+ return WasmMemory;
+ }
+
+ Operand *sanitizeAddress(Operand *Base, uint32_t Offset) {
+ SizeT MemSize = Module->module->min_mem_pages * WASM_PAGE_SIZE;
+
+ bool ConstZeroBase = false;
+
+ // first, add the index and the offset together.
+ if (auto *ConstBase = llvm::dyn_cast<ConstantInteger32>(Base)) {
+ uint32_t RealOffset = Offset + ConstBase->getValue();
+ if (RealOffset >= MemSize) {
+ // We've proven this will always be an out of bounds access, so insert
+ // an unconditional trap.
+ Control()->appendInst(InstUnreachable::create(Func));
+ // It doesn't matter what we return here, so return something that will
+ // allow the rest of code generation to happen.
+ //
+ // We might be tempted to just abort translation here, but out of bounds
+ // memory access is a runtime trap, not a compile error.
+ return Ctx->getConstantZero(getPointerType());
+ }
+ Base = Ctx->getConstantInt32(RealOffset);
+ ConstZeroBase = (0 == RealOffset);
+ } else if (0 != Offset) {
+ auto *Addr = makeVariable(Ice::getPointerType());
+ auto *OffsetConstant = Ctx->getConstantInt32(Offset);
+ Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Add,
+ Addr, Base, OffsetConstant));
+
+ Base = Addr;
+ }
+
+ // Do the bounds check.
+ //
+ // TODO (eholk): Add a command line argument to control whether bounds
+ // checks are inserted, and maybe add a way to duplicate bounds checks to
+ // get a better sense of the overhead.
+ if (!llvm::dyn_cast<ConstantInteger32>(Base)) {
+ // TODO (eholk): creating a new basic block on every memory access is
+ // terrible (see https://goo.gl/Zj7DTr). Try adding a new instruction that
+ // encapsulates this "abort if false" pattern.
+ auto *CheckPassed = Func->makeNode();
+ auto *CheckFailed = getBoundsFailTarget();
+
+ auto *Check = makeVariable(IceType_i1);
+ Control()->appendInst(InstIcmp::create(Func, InstIcmp::Ult, Check, Base,
+ Ctx->getConstantInt32(MemSize)));
+ Control()->appendInst(
+ InstBr::create(Func, Check, CheckPassed, CheckFailed));
+
+ *ControlPtr = OperandNode(CheckPassed);
+ }
+
+ Ice::Operand *RealAddr = nullptr;
+ auto MemBase = getWasmMemory();
+ if (!ConstZeroBase) {
+ auto RealAddrV = Func->makeVariable(Ice::getPointerType());
+ Control()->appendInst(InstArithmetic::create(Func, InstArithmetic::Add,
+ RealAddrV, Base, MemBase));
+
+ RealAddr = RealAddrV;
+ } else {
+ RealAddr = MemBase;
+ }
+ return RealAddr;
+ }
+
template <typename F = std::function<void(Ostream &)>> void log(F Fn) const {
if (BuildDefs::dump() && (getFlags().getVerbose() & IceV_Wasm)) {
Fn(Ctx->getStrDump());
@@ -1390,6 +1407,7 @@ std::unique_ptr<Cfg> WasmTranslator::translateFunction(Zone *Zone,
FunctionBody &Body) {
OstreamLocker L1(Ctx);
auto Func = Cfg::create(Ctx, getNextSequenceNumber());
+ TimerMarker T(TimerStack::TT_wasmGenIce, Func.get());
Ice::CfgLocalAllocatorScope L2(Func.get());
// TODO(eholk): parse the function signature...
@@ -1419,6 +1437,8 @@ WasmTranslator::WasmTranslator(GlobalContext *Ctx)
void WasmTranslator::translate(
const std::string &IRFilename,
std::unique_ptr<llvm::DataStreamer> InputStream) {
+ TimerMarker T(TimerStack::TT_wasm, Ctx);
+
LOG(out << "Initializing v8/wasm stuff..."
<< "\n");
Zone Zone;
@@ -1533,7 +1553,7 @@ void WasmTranslator::translate(
// Global variables, etc go here.
auto *WasmMemory = VariableDeclaration::createExternal(Globals.get());
- WasmMemory->setName(Ctx->getGlobalString("WASM_MEMORY"));
+ WasmMemory->setName(Ctx->getGlobalString("WASM_DATA_INIT"));
// Fill in the segments
SizeT WritePtr = 0;
@@ -1562,13 +1582,6 @@ void WasmTranslator::translate(
Globals.get(), reinterpret_cast<const char *>(&WritePtr),
sizeof(WritePtr)));
- // Pad the rest with zeros
- SizeT DataSize = Module->min_mem_pages * WASM_PAGE_SIZE;
- if (WritePtr < DataSize) {
- WasmMemory->addInitializer(VariableDeclaration::ZeroInitializer::create(
- Globals.get(), DataSize - WritePtr));
- }
-
// Save the number of pages for the runtime
auto *GlobalNumPages = VariableDeclaration::createExternal(Globals.get());
GlobalNumPages->setName(Ctx->getGlobalString("WASM_NUM_PAGES"));
@@ -1594,9 +1607,12 @@ void WasmTranslator::translate(
Body.start = Buffer.data() + Fn.code_start_offset;
Body.end = Buffer.data() + Fn.code_end_offset;
- auto Func = translateFunction(&Zone, Body);
- Func->setFunctionName(Ctx->getGlobalString(FnName));
-
+ std::unique_ptr<Cfg> Func = nullptr;
+ {
+ TimerMarker T_func(getContext(), FnName);
+ Func = translateFunction(&Zone, Body);
+ Func->setFunctionName(Ctx->getGlobalString(FnName));
+ }
Ctx->optQueueBlockingPush(makeUnique<CfgOptWorkItem>(std::move(Func)));
LOG(out << "done.\n");
}
« runtime/wasm-runtime.cpp ('K') | « src/IceTimerTree.def ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698