diff options
Diffstat (limited to 'src/passes')
-rw-r--r-- | src/passes/AlignmentLowering.cpp | 52 | ||||
-rw-r--r-- | src/passes/AvoidReinterprets.cpp | 9 | ||||
-rw-r--r-- | src/passes/InstrumentMemory.cpp | 17 | ||||
-rw-r--r-- | src/passes/MemoryPacking.cpp | 22 | ||||
-rw-r--r-- | src/passes/OptimizeInstructions.cpp | 18 | ||||
-rw-r--r-- | src/passes/Print.cpp | 5 | ||||
-rw-r--r-- | src/passes/SafeHeap.cpp | 102 | ||||
-rw-r--r-- | src/passes/StackIR.cpp | 2 |
8 files changed, 129 insertions, 98 deletions
diff --git a/src/passes/AlignmentLowering.cpp b/src/passes/AlignmentLowering.cpp index b12e49c4f..8cab58072 100644 --- a/src/passes/AlignmentLowering.cpp +++ b/src/passes/AlignmentLowering.cpp @@ -34,9 +34,10 @@ struct AlignmentLowering : public WalkerPass<PostWalker<AlignmentLowering>> { if (curr->align == 0 || curr->align == curr->bytes) { return curr; } + auto indexType = getModule()->memory.indexType; Builder builder(*getModule()); assert(curr->type == Type::i32); - auto temp = builder.addVar(getFunction(), Type::i32); + auto temp = builder.addVar(getFunction(), indexType); Expression* ret; if (curr->bytes == 2) { ret = builder.makeBinary( @@ -45,7 +46,7 @@ struct AlignmentLowering : public WalkerPass<PostWalker<AlignmentLowering>> { false, curr->offset, 1, - builder.makeLocalGet(temp, Type::i32), + builder.makeLocalGet(temp, indexType), Type::i32), builder.makeBinary( ShlInt32, @@ -53,7 +54,7 @@ struct AlignmentLowering : public WalkerPass<PostWalker<AlignmentLowering>> { false, curr->offset + 1, 1, - builder.makeLocalGet(temp, Type::i32), + builder.makeLocalGet(temp, indexType), Type::i32), builder.makeConst(int32_t(8)))); if (curr->signed_) { @@ -69,7 +70,7 @@ struct AlignmentLowering : public WalkerPass<PostWalker<AlignmentLowering>> { false, curr->offset, 1, - builder.makeLocalGet(temp, Type::i32), + builder.makeLocalGet(temp, indexType), Type::i32), builder.makeBinary( ShlInt32, @@ -77,7 +78,7 @@ struct AlignmentLowering : public WalkerPass<PostWalker<AlignmentLowering>> { false, curr->offset + 1, 1, - builder.makeLocalGet(temp, Type::i32), + builder.makeLocalGet(temp, indexType), Type::i32), builder.makeConst(int32_t(8)))), builder.makeBinary( @@ -88,7 +89,7 @@ struct AlignmentLowering : public WalkerPass<PostWalker<AlignmentLowering>> { false, curr->offset + 2, 1, - builder.makeLocalGet(temp, Type::i32), + builder.makeLocalGet(temp, indexType), Type::i32), builder.makeConst(int32_t(16))), builder.makeBinary( @@ -97,7 +98,7 @@ struct AlignmentLowering : public WalkerPass<PostWalker<AlignmentLowering>> { false, curr->offset + 3, 1, - builder.makeLocalGet(temp, Type::i32), + builder.makeLocalGet(temp, indexType), Type::i32), builder.makeConst(int32_t(24))))); } else if (curr->align == 2) { @@ -107,7 +108,7 @@ struct AlignmentLowering : public WalkerPass<PostWalker<AlignmentLowering>> { false, curr->offset, 2, - builder.makeLocalGet(temp, Type::i32), + builder.makeLocalGet(temp, indexType), Type::i32), builder.makeBinary( ShlInt32, @@ -115,7 +116,7 @@ struct AlignmentLowering : public WalkerPass<PostWalker<AlignmentLowering>> { false, curr->offset + 2, 2, - builder.makeLocalGet(temp, Type::i32), + builder.makeLocalGet(temp, indexType), Type::i32), builder.makeConst(int32_t(16)))); } else { @@ -134,7 +135,8 @@ struct AlignmentLowering : public WalkerPass<PostWalker<AlignmentLowering>> { } Builder builder(*getModule()); assert(curr->value->type == Type::i32); - auto tempPtr = builder.addVar(getFunction(), Type::i32); + auto indexType = getModule()->memory.indexType; + auto tempPtr = builder.addVar(getFunction(), indexType); auto tempValue = builder.addVar(getFunction(), Type::i32); auto* block = builder.makeBlock({builder.makeLocalSet(tempPtr, curr->ptr), @@ -144,14 +146,14 @@ struct AlignmentLowering : public WalkerPass<PostWalker<AlignmentLowering>> { builder.makeStore(1, curr->offset, 1, - builder.makeLocalGet(tempPtr, Type::i32), + builder.makeLocalGet(tempPtr, indexType), builder.makeLocalGet(tempValue, Type::i32), Type::i32)); block->list.push_back(builder.makeStore( 1, curr->offset + 1, 1, - builder.makeLocalGet(tempPtr, Type::i32), + builder.makeLocalGet(tempPtr, indexType), builder.makeBinary(ShrUInt32, builder.makeLocalGet(tempValue, Type::i32), builder.makeConst(int32_t(8))), @@ -162,14 +164,14 @@ struct AlignmentLowering : public WalkerPass<PostWalker<AlignmentLowering>> { builder.makeStore(1, curr->offset, 1, - builder.makeLocalGet(tempPtr, Type::i32), + builder.makeLocalGet(tempPtr, indexType), builder.makeLocalGet(tempValue, Type::i32), Type::i32)); block->list.push_back(builder.makeStore( 1, curr->offset + 1, 1, - builder.makeLocalGet(tempPtr, Type::i32), + builder.makeLocalGet(tempPtr, indexType), builder.makeBinary(ShrUInt32, builder.makeLocalGet(tempValue, Type::i32), builder.makeConst(int32_t(8))), @@ -178,7 +180,7 @@ struct AlignmentLowering : public WalkerPass<PostWalker<AlignmentLowering>> { 1, curr->offset + 2, 1, - builder.makeLocalGet(tempPtr, Type::i32), + builder.makeLocalGet(tempPtr, indexType), builder.makeBinary(ShrUInt32, builder.makeLocalGet(tempValue, Type::i32), builder.makeConst(int32_t(16))), @@ -187,7 +189,7 @@ struct AlignmentLowering : public WalkerPass<PostWalker<AlignmentLowering>> { 1, curr->offset + 3, 1, - builder.makeLocalGet(tempPtr, Type::i32), + builder.makeLocalGet(tempPtr, indexType), builder.makeBinary(ShrUInt32, builder.makeLocalGet(tempValue, Type::i32), builder.makeConst(int32_t(24))), @@ -197,14 +199,14 @@ struct AlignmentLowering : public WalkerPass<PostWalker<AlignmentLowering>> { builder.makeStore(2, curr->offset, 2, - builder.makeLocalGet(tempPtr, Type::i32), + builder.makeLocalGet(tempPtr, indexType), builder.makeLocalGet(tempValue, Type::i32), Type::i32)); block->list.push_back(builder.makeStore( 2, curr->offset + 2, 2, - builder.makeLocalGet(tempPtr, Type::i32), + builder.makeLocalGet(tempPtr, indexType), builder.makeBinary(ShrUInt32, builder.makeLocalGet(tempValue, Type::i32), builder.makeConst(int32_t(16))), @@ -254,14 +256,15 @@ struct AlignmentLowering : public WalkerPass<PostWalker<AlignmentLowering>> { break; } // Load two 32-bit pieces, and combine them. - auto temp = builder.addVar(getFunction(), Type::i32); + auto indexType = getModule()->memory.indexType; + auto temp = builder.addVar(getFunction(), indexType); auto* set = builder.makeLocalSet(temp, curr->ptr); Expression* low = lowerLoadI32(builder.makeLoad(4, false, curr->offset, curr->align, - builder.makeLocalGet(temp, Type::i32), + builder.makeLocalGet(temp, indexType), Type::i32)); low = builder.makeUnary(ExtendUInt32, low); // Note that the alignment is assumed to be the same here, even though @@ -273,7 +276,7 @@ struct AlignmentLowering : public WalkerPass<PostWalker<AlignmentLowering>> { false, curr->offset + 4, curr->align, - builder.makeLocalGet(temp, Type::i32), + builder.makeLocalGet(temp, indexType), Type::i32)); high = builder.makeUnary(ExtendUInt32, high); high = @@ -332,7 +335,8 @@ struct AlignmentLowering : public WalkerPass<PostWalker<AlignmentLowering>> { value = builder.makeUnary(ReinterpretFloat64, value); } // Store as two 32-bit pieces. - auto tempPtr = builder.addVar(getFunction(), Type::i32); + auto indexType = getModule()->memory.indexType; + auto tempPtr = builder.addVar(getFunction(), indexType); auto* setPtr = builder.makeLocalSet(tempPtr, curr->ptr); auto tempValue = builder.addVar(getFunction(), Type::i64); auto* setValue = builder.makeLocalSet(tempValue, value); @@ -342,7 +346,7 @@ struct AlignmentLowering : public WalkerPass<PostWalker<AlignmentLowering>> { builder.makeStore(4, curr->offset, curr->align, - builder.makeLocalGet(tempPtr, Type::i32), + builder.makeLocalGet(tempPtr, indexType), low, Type::i32)); Expression* high = @@ -358,7 +362,7 @@ struct AlignmentLowering : public WalkerPass<PostWalker<AlignmentLowering>> { builder.makeStore(4, curr->offset + 4, curr->align, - builder.makeLocalGet(tempPtr, Type::i32), + builder.makeLocalGet(tempPtr, indexType), high, Type::i32)); replacement = builder.makeBlock({setPtr, setValue, low, high}); diff --git a/src/passes/AvoidReinterprets.cpp b/src/passes/AvoidReinterprets.cpp index 8668b9703..cc5871a2a 100644 --- a/src/passes/AvoidReinterprets.cpp +++ b/src/passes/AvoidReinterprets.cpp @@ -117,12 +117,13 @@ struct AvoidReinterprets : public WalkerPass<PostWalker<AvoidReinterprets>> { void optimize(Function* func) { std::set<Load*> unoptimizables; + auto indexType = getModule()->memory.indexType; for (auto& pair : infos) { auto* load = pair.first; auto& info = pair.second; if (info.reinterpreted && canReplaceWithReinterpret(load)) { // We should use another load here, to avoid reinterprets. - info.ptrLocal = Builder::addVar(func, Type::i32); + info.ptrLocal = Builder::addVar(func, indexType); info.reinterpretedLocal = Builder::addVar(func, load->type.reinterpret()); } else { @@ -176,7 +177,8 @@ struct AvoidReinterprets : public WalkerPass<PostWalker<AvoidReinterprets>> { auto& info = iter->second; Builder builder(*module); auto* ptr = curr->ptr; - curr->ptr = builder.makeLocalGet(info.ptrLocal, Type::i32); + auto indexType = getModule()->memory.indexType; + curr->ptr = builder.makeLocalGet(info.ptrLocal, indexType); // Note that the other load can have its sign set to false - if the // original were an integer, the other is a float anyhow; and if // original were a float, we don't know what sign to use. @@ -185,7 +187,7 @@ struct AvoidReinterprets : public WalkerPass<PostWalker<AvoidReinterprets>> { builder.makeLocalSet( info.reinterpretedLocal, makeReinterpretedLoad( - curr, builder.makeLocalGet(info.ptrLocal, Type::i32))), + curr, builder.makeLocalGet(info.ptrLocal, indexType))), curr})); } } @@ -201,6 +203,7 @@ struct AvoidReinterprets : public WalkerPass<PostWalker<AvoidReinterprets>> { } } finalOptimizer(infos, localGraph, getModule(), getPassOptions()); + finalOptimizer.setModule(getModule()); finalOptimizer.walk(func->body); } }; diff --git a/src/passes/InstrumentMemory.cpp b/src/passes/InstrumentMemory.cpp index fca3ff510..9e4788456 100644 --- a/src/passes/InstrumentMemory.cpp +++ b/src/passes/InstrumentMemory.cpp @@ -78,12 +78,14 @@ struct InstrumentMemory : public WalkerPass<PostWalker<InstrumentMemory>> { void visitLoad(Load* curr) { id++; Builder builder(*getModule()); + auto indexType = getModule()->memory.indexType; + auto offset = builder.makeConstPtr(curr->offset.addr); curr->ptr = builder.makeCall(load_ptr, {builder.makeConst(int32_t(id)), builder.makeConst(int32_t(curr->bytes)), - builder.makeConst(int32_t(curr->offset.addr)), + offset, curr->ptr}, - Type::i32); + indexType); Name target; switch (curr->type.getBasic()) { case Type::i32: @@ -108,12 +110,14 @@ struct InstrumentMemory : public WalkerPass<PostWalker<InstrumentMemory>> { void visitStore(Store* curr) { id++; Builder builder(*getModule()); + auto indexType = getModule()->memory.indexType; + auto offset = builder.makeConstPtr(curr->offset.addr); curr->ptr = builder.makeCall(store_ptr, {builder.makeConst(int32_t(id)), builder.makeConst(int32_t(curr->bytes)), - builder.makeConst(int32_t(curr->offset.addr)), + offset, curr->ptr}, - Type::i32); + indexType); Name target; switch (curr->value->type.getBasic()) { case Type::i32: @@ -136,14 +140,15 @@ struct InstrumentMemory : public WalkerPass<PostWalker<InstrumentMemory>> { } void visitModule(Module* curr) { + auto indexType = curr->memory.indexType; addImport( - curr, load_ptr, {Type::i32, Type::i32, Type::i32, Type::i32}, Type::i32); + curr, load_ptr, {Type::i32, Type::i32, indexType, indexType}, indexType); addImport(curr, load_val_i32, {Type::i32, Type::i32}, Type::i32); addImport(curr, load_val_i64, {Type::i32, Type::i64}, Type::i64); addImport(curr, load_val_f32, {Type::i32, Type::f32}, Type::f32); addImport(curr, load_val_f64, {Type::i32, Type::f64}, Type::f64); addImport( - curr, store_ptr, {Type::i32, Type::i32, Type::i32, Type::i32}, Type::i32); + curr, store_ptr, {Type::i32, Type::i32, indexType, indexType}, indexType); addImport(curr, store_val_i32, {Type::i32, Type::i32}, Type::i32); addImport(curr, store_val_i64, {Type::i32, Type::i64}, Type::i64); addImport(curr, store_val_f32, {Type::i32, Type::f32}, Type::f32); diff --git a/src/passes/MemoryPacking.cpp b/src/passes/MemoryPacking.cpp index eac7fb7f0..1018ce1c7 100644 --- a/src/passes/MemoryPacking.cpp +++ b/src/passes/MemoryPacking.cpp @@ -76,9 +76,14 @@ const size_t DATA_DROP_SIZE = 3; namespace { -Expression* makeShiftedMemorySize(Builder& builder) { +Expression* +makeGtShiftedMemorySize(Builder& builder, Module& module, MemoryInit* curr) { return builder.makeBinary( - ShlInt32, builder.makeMemorySize(), builder.makeConst(int32_t(16))); + module.memory.is64() ? GtUInt64 : GtUInt32, + curr->dest, + builder.makeBinary(module.memory.is64() ? ShlInt64 : ShlInt32, + builder.makeMemorySize(), + builder.makeConstPtr(16))); } } // anonymous namespace @@ -317,10 +322,9 @@ void MemoryPacking::optimizeBulkMemoryOps(PassRunner* runner, Module* module) { assert(!mustNop || !mustTrap); if (mustNop) { // Offset and size are 0, so just trap if dest > memory.size - replaceCurrent(builder.makeIf( - builder.makeBinary( - GtUInt32, curr->dest, makeShiftedMemorySize(builder)), - builder.makeUnreachable())); + replaceCurrent( + builder.makeIf(makeGtShiftedMemorySize(builder, *getModule(), curr), + builder.makeUnreachable())); } else if (mustTrap) { // Drop dest, offset, and size then trap replaceCurrent(builder.blockify(builder.makeDrop(curr->dest), @@ -333,8 +337,7 @@ void MemoryPacking::optimizeBulkMemoryOps(PassRunner* runner, Module* module) { replaceCurrent(builder.makeIf( builder.makeBinary( OrInt32, - builder.makeBinary( - GtUInt32, curr->dest, makeShiftedMemorySize(builder)), + makeGtShiftedMemorySize(builder, *getModule(), curr), builder.makeBinary(OrInt32, curr->offset, curr->size)), builder.makeUnreachable())); } @@ -527,8 +530,7 @@ void MemoryPacking::createReplacements(Module* module, Expression* result = builder.makeIf( builder.makeBinary( OrInt32, - builder.makeBinary( - GtUInt32, init->dest, makeShiftedMemorySize(builder)), + makeGtShiftedMemorySize(builder, *module, init), builder.makeGlobalGet(getDropStateGlobal(), Type::i32)), builder.makeUnreachable()); replacements[init] = [result](Function*) { return result; }; diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp index e3d2b3a57..9cc16004d 100644 --- a/src/passes/OptimizeInstructions.cpp +++ b/src/passes/OptimizeInstructions.cpp @@ -1107,14 +1107,20 @@ private: // as for readability. auto* last = ptr->dynCast<Const>(); if (last) { - // don't do this if it would wrap the pointer - uint64_t value64 = last->value.geti32(); + uint64_t value64 = last->value.getInteger(); uint64_t offset64 = offset; - if (value64 <= uint64_t(std::numeric_limits<int32_t>::max()) && - offset64 <= uint64_t(std::numeric_limits<int32_t>::max()) && - value64 + offset64 <= uint64_t(std::numeric_limits<int32_t>::max())) { - last->value = Literal(int32_t(value64 + offset64)); + if (getModule()->memory.is64()) { + last->value = Literal(int64_t(value64 + offset64)); offset = 0; + } else { + // don't do this if it would wrap the pointer + if (value64 <= uint64_t(std::numeric_limits<int32_t>::max()) && + offset64 <= uint64_t(std::numeric_limits<int32_t>::max()) && + value64 + offset64 <= + uint64_t(std::numeric_limits<int32_t>::max())) { + last->value = Literal(int32_t(value64 + offset64)); + offset = 0; + } } } } diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index 916615e07..6955a7a5e 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -2298,6 +2298,9 @@ struct PrintSExpression : public OverriddenVisitor<PrintSExpression> { o << '('; printMedium(o, "shared "); } + if (curr->is64()) { + o << "i64 "; + } o << curr->initial; if (curr->hasMax()) { o << ' ' << curr->max; @@ -2446,7 +2449,7 @@ struct PrintSExpression : public OverriddenVisitor<PrintSExpression> { << section.data.size(); bool isPrintable = true; for (auto c : section.data) { - if (!isprint(c)) { + if (!isprint(static_cast<unsigned char>(c))) { isPrintable = false; break; } diff --git a/src/passes/SafeHeap.cpp b/src/passes/SafeHeap.cpp index 108739d66..0335c174e 100644 --- a/src/passes/SafeHeap.cpp +++ b/src/passes/SafeHeap.cpp @@ -85,10 +85,7 @@ struct AccessInstrumenter : public WalkerPass<PostWalker<AccessInstrumenter>> { Builder builder(*getModule()); replaceCurrent( builder.makeCall(getLoadName(curr), - { - curr->ptr, - builder.makeConst(Literal(int32_t(curr->offset))), - }, + {curr->ptr, builder.makeConstPtr(curr->offset.addr)}, curr->type)); } @@ -97,14 +94,10 @@ struct AccessInstrumenter : public WalkerPass<PostWalker<AccessInstrumenter>> { return; } Builder builder(*getModule()); - replaceCurrent( - builder.makeCall(getStoreName(curr), - { - curr->ptr, - builder.makeConst(Literal(int32_t(curr->offset))), - curr->value, - }, - Type::none)); + replaceCurrent(builder.makeCall( + getStoreName(curr), + {curr->ptr, builder.makeConstPtr(curr->offset.addr), curr->value}, + Type::none)); } }; @@ -125,6 +118,7 @@ struct SafeHeap : public Pass { void addImports(Module* module) { ImportInfo info(*module); + auto indexType = module->memory.indexType; // Older emscripten imports env.DYNAMICTOP_PTR. // Newer emscripten imports or exports emscripten_get_sbrk_ptr(). if (auto* existing = info.getImportedGlobal(ENV, DYNAMICTOP_PTR_IMPORT)) { @@ -140,7 +134,7 @@ struct SafeHeap : public Pass { import->name = getSbrkPtr = GET_SBRK_PTR; import->module = ENV; import->base = GET_SBRK_PTR; - import->sig = Signature(Type::none, Type::i32); + import->sig = Signature(Type::none, indexType); module->addFunction(import); } if (auto* existing = info.getImportedFunction(ENV, SEGFAULT_IMPORT)) { @@ -251,25 +245,27 @@ struct SafeHeap : public Pass { auto* func = new Function; func->name = name; // pointer, offset - func->sig = Signature({Type::i32, Type::i32}, style.type); - func->vars.push_back(Type::i32); // pointer + offset + auto indexType = module->memory.indexType; + func->sig = Signature({indexType, indexType}, style.type); + func->vars.push_back(indexType); // pointer + offset Builder builder(*module); auto* block = builder.makeBlock(); block->list.push_back(builder.makeLocalSet( 2, - builder.makeBinary(AddInt32, - builder.makeLocalGet(0, Type::i32), - builder.makeLocalGet(1, Type::i32)))); + builder.makeBinary(module->memory.is64() ? AddInt64 : AddInt32, + builder.makeLocalGet(0, indexType), + builder.makeLocalGet(1, indexType)))); // check for reading past valid memory: if pointer + offset + bytes - block->list.push_back(makeBoundsCheck(style.type, builder, 2, style.bytes)); + block->list.push_back( + makeBoundsCheck(style.type, builder, 2, style.bytes, module)); // check proper alignment if (style.align > 1) { - block->list.push_back(makeAlignCheck(style.align, builder, 2)); + block->list.push_back(makeAlignCheck(style.align, builder, 2, module)); } // do the load auto* load = module->allocator.alloc<Load>(); *load = style; // basically the same as the template we are given! - load->ptr = builder.makeLocalGet(2, Type::i32); + load->ptr = builder.makeLocalGet(2, indexType); Expression* last = load; if (load->isAtomic && load->signed_) { // atomic loads cannot be signed, manually sign it @@ -291,26 +287,27 @@ struct SafeHeap : public Pass { auto* func = new Function; func->name = name; // pointer, offset, value - func->sig = Signature({Type::i32, Type::i32, style.valueType}, Type::none); - func->vars.push_back(Type::i32); // pointer + offset + auto indexType = module->memory.indexType; + func->sig = Signature({indexType, indexType, style.valueType}, Type::none); + func->vars.push_back(indexType); // pointer + offset Builder builder(*module); auto* block = builder.makeBlock(); block->list.push_back(builder.makeLocalSet( 3, - builder.makeBinary(AddInt32, - builder.makeLocalGet(0, Type::i32), - builder.makeLocalGet(1, Type::i32)))); + builder.makeBinary(module->memory.is64() ? AddInt64 : AddInt32, + builder.makeLocalGet(0, indexType), + builder.makeLocalGet(1, indexType)))); // check for reading past valid memory: if pointer + offset + bytes block->list.push_back( - makeBoundsCheck(style.valueType, builder, 3, style.bytes)); + makeBoundsCheck(style.valueType, builder, 3, style.bytes, module)); // check proper alignment if (style.align > 1) { - block->list.push_back(makeAlignCheck(style.align, builder, 3)); + block->list.push_back(makeAlignCheck(style.align, builder, 3, module)); } // do the store auto* store = module->allocator.alloc<Store>(); *store = style; // basically the same as the template we are given! - store->ptr = builder.makeLocalGet(3, Type::i32); + store->ptr = builder.makeLocalGet(3, indexType); store->value = builder.makeLocalGet(2, style.valueType); block->list.push_back(store); block->finalize(Type::none); @@ -318,42 +315,53 @@ struct SafeHeap : public Pass { module->addFunction(func); } - Expression* makeAlignCheck(Address align, Builder& builder, Index local) { + Expression* + makeAlignCheck(Address align, Builder& builder, Index local, Module* module) { + auto indexType = module->memory.indexType; + Expression* ptrBits = builder.makeLocalGet(local, indexType); + if (module->memory.is64()) { + ptrBits = builder.makeUnary(WrapInt64, ptrBits); + } return builder.makeIf( - builder.makeBinary(AndInt32, - builder.makeLocalGet(local, Type::i32), - builder.makeConst(Literal(int32_t(align - 1)))), + builder.makeBinary( + AndInt32, ptrBits, builder.makeConst(int32_t(align - 1))), builder.makeCall(alignfault, {}, Type::none)); } - Expression* - makeBoundsCheck(Type type, Builder& builder, Index local, Index bytes) { - auto upperOp = options.lowMemoryUnused ? LtUInt32 : EqInt32; + Expression* makeBoundsCheck( + Type type, Builder& builder, Index local, Index bytes, Module* module) { + auto indexType = module->memory.indexType; + auto upperOp = module->memory.is64() + ? options.lowMemoryUnused ? LtUInt64 : EqInt64 + : options.lowMemoryUnused ? LtUInt32 : EqInt32; auto upperBound = options.lowMemoryUnused ? PassOptions::LowMemoryBound : 0; Expression* brkLocation; if (sbrk.is()) { - brkLocation = builder.makeCall( - sbrk, {builder.makeConst(Literal(int32_t(0)))}, Type::i32); + brkLocation = + builder.makeCall(sbrk, {builder.makeConstPtr(0)}, indexType); } else { Expression* sbrkPtr; if (dynamicTopPtr.is()) { - sbrkPtr = builder.makeGlobalGet(dynamicTopPtr, Type::i32); + sbrkPtr = builder.makeGlobalGet(dynamicTopPtr, indexType); } else { - sbrkPtr = builder.makeCall(getSbrkPtr, {}, Type::i32); + sbrkPtr = builder.makeCall(getSbrkPtr, {}, indexType); } - brkLocation = builder.makeLoad(4, false, 0, 4, sbrkPtr, Type::i32); + auto size = module->memory.is64() ? 8 : 4; + brkLocation = builder.makeLoad(size, false, 0, size, sbrkPtr, indexType); } + auto gtuOp = module->memory.is64() ? GtUInt64 : GtUInt32; + auto addOp = module->memory.is64() ? AddInt64 : AddInt32; return builder.makeIf( builder.makeBinary( OrInt32, builder.makeBinary(upperOp, - builder.makeLocalGet(local, Type::i32), - builder.makeConst(Literal(int32_t(upperBound)))), + builder.makeLocalGet(local, indexType), + builder.makeConstPtr(upperBound)), builder.makeBinary( - GtUInt32, - builder.makeBinary(AddInt32, - builder.makeLocalGet(local, Type::i32), - builder.makeConst(Literal(int32_t(bytes)))), + gtuOp, + builder.makeBinary(addOp, + builder.makeLocalGet(local, indexType), + builder.makeConstPtr(bytes)), brkLocation)), builder.makeCall(segfault, {}, Type::none)); } diff --git a/src/passes/StackIR.cpp b/src/passes/StackIR.cpp index a628468fb..ee2062b3d 100644 --- a/src/passes/StackIR.cpp +++ b/src/passes/StackIR.cpp @@ -36,7 +36,7 @@ struct GenerateStackIR : public WalkerPass<PostWalker<GenerateStackIR>> { bool modifiesBinaryenIR() override { return false; } void doWalkFunction(Function* func) { - StackIRGenerator stackIRGen(getModule()->allocator, func); + StackIRGenerator stackIRGen(*getModule(), func); stackIRGen.write(); func->stackIR = make_unique<StackIR>(); func->stackIR->swap(stackIRGen.getStackIR()); |