Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/binaryen-c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2633,12 +2633,14 @@ void BinaryenMemoryGrowSetDelta(BinaryenExpressionRef expr,
bool BinaryenLoadIsAtomic(BinaryenExpressionRef expr) {
auto* expression = (Expression*)expr;
assert(expression->is<Load>());
return static_cast<Load*>(expression)->isAtomic;
return static_cast<Load*>(expression)->isAtomic();
}

void BinaryenLoadSetAtomic(BinaryenExpressionRef expr, bool isAtomic) {
auto* expression = (Expression*)expr;
assert(expression->is<Load>());
static_cast<Load*>(expression)->isAtomic = isAtomic != 0;
static_cast<Load*>(expression)->order =
isAtomic ? MemoryOrder::SeqCst : MemoryOrder::Unordered;
}
bool BinaryenLoadIsSigned(BinaryenExpressionRef expr) {
auto* expression = (Expression*)expr;
Expand Down
2 changes: 1 addition & 1 deletion src/ir/cost.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ struct CostAnalyzer : public OverriddenVisitor<CostAnalyzer, CostType> {
CostType visitGlobalGet(GlobalGet* curr) { return 1; }
CostType visitGlobalSet(GlobalSet* curr) { return 2 + visit(curr->value); }
CostType visitLoad(Load* curr) {
return 1 + visit(curr->ptr) + AtomicCost * curr->isAtomic;
return 1 + visit(curr->ptr) + AtomicCost * curr->isAtomic();
}
CostType visitStore(Store* curr) {
return 2 + visit(curr->ptr) + visit(curr->value) +
Expand Down
2 changes: 1 addition & 1 deletion src/ir/effects.h
Original file line number Diff line number Diff line change
Expand Up @@ -598,7 +598,7 @@ class EffectAnalyzer {
}
void visitLoad(Load* curr) {
parent.readsMemory = true;
parent.isAtomic |= curr->isAtomic;
parent.isAtomic |= curr->isAtomic();
parent.implicitTrap = true;
}
void visitStore(Store* curr) {
Expand Down
2 changes: 1 addition & 1 deletion src/ir/load-utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ inline bool isSignRelevant(Load* load) {
}

// check if a load can be signed (which some opts want to do)
inline bool canBeSigned(Load* load) { return !load->isAtomic; }
inline bool canBeSigned(Load* load) { return !load->isAtomic(); }

} // namespace wasm::LoadUtils

Expand Down
2 changes: 1 addition & 1 deletion src/ir/properties.h
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,7 @@ inline MemoryOrder getMemoryOrder(Expression* curr) {
return set->order;
}
if (auto* load = curr->dynCast<Load>()) {
return load->isAtomic ? MemoryOrder::SeqCst : MemoryOrder::Unordered;
return load->order;
}
if (auto* store = curr->dynCast<Store>()) {
return store->isAtomic ? MemoryOrder::SeqCst : MemoryOrder::Unordered;
Expand Down
2 changes: 1 addition & 1 deletion src/passes/I64ToI32Lowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,7 @@ struct I64ToI32Lowering : public WalkerPass<PostWalker<I64ToI32Lowering>> {
if (curr->type != Type::i64) {
return;
}
assert(!curr->isAtomic && "64-bit atomic load not implemented");
assert(!curr->isAtomic() && "64-bit atomic load not implemented");
TempVar lowBits = getTemp();
TempVar highBits = getTemp();
TempVar ptrTemp = getTemp();
Expand Down
4 changes: 2 additions & 2 deletions src/passes/OptimizeInstructions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1049,7 +1049,7 @@ struct OptimizeInstructions
// extend operation.
bool willBeSigned = curr->op == ExtendSInt32 && load->bytes == 4;
if (!(curr->op == ExtendUInt32 && load->bytes <= 2 && load->signed_) &&
!(willBeSigned && load->isAtomic)) {
!(willBeSigned && load->isAtomic())) {
if (willBeSigned) {
load->signed_ = true;
}
Expand Down Expand Up @@ -1092,7 +1092,7 @@ struct OptimizeInstructions
// i32.reinterpret_f32(f32.load(x)) => i32.load(x)
// i64.reinterpret_f64(f64.load(x)) => i64.load(x)
if (auto* load = curr->value->dynCast<Load>()) {
if (!load->isAtomic && load->bytes == curr->type.getByteSize()) {
if (!load->isAtomic() && load->bytes == curr->type.getByteSize()) {
load->type = curr->type;
return replaceCurrent(load);
}
Expand Down
2 changes: 1 addition & 1 deletion src/passes/PickLoadSigns.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ struct PickLoadSigns : public WalkerPass<ExpressionStackWalker<PickLoadSigns>> {
continue;
}
// Atomic operations are always unsigned, never signed.
if (load->isAtomic) {
if (load->isAtomic()) {
continue;
}
// we can pick the optimal one. our hope is to remove 2 items per
Expand Down
2 changes: 1 addition & 1 deletion src/passes/Print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,7 @@ struct PrintExpressionContents
}
void visitLoad(Load* curr) {
prepareColor(o) << forceConcrete(curr->type, curr->align);
if (curr->isAtomic) {
if (curr->isAtomic()) {
o << ".atomic";
}
o << ".load";
Expand Down
7 changes: 4 additions & 3 deletions src/passes/SafeHeap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ static Name getLoadName(Load* curr) {
if (LoadUtils::isSignRelevant(curr) && !curr->signed_) {
ret += "U_";
}
if (curr->isAtomic) {
if (curr->isAtomic()) {
ret += "A";
} else {
ret += std::to_string(curr->align);
Expand Down Expand Up @@ -233,7 +233,8 @@ struct SafeHeap : public Pass {
continue;
}
for (auto isAtomic : {true, false}) {
load.isAtomic = isAtomic;
load.order =
isAtomic ? MemoryOrder::SeqCst : MemoryOrder::Unordered;
if (isAtomic &&
!isPossibleAtomicOperation(
align, bytes, module->memories[0]->shared, type)) {
Expand Down Expand Up @@ -321,7 +322,7 @@ struct SafeHeap : public Pass {
*load = style; // basically the same as the template we are given!
load->ptr = builder.makeLocalGet(2, addressType);
Expression* last = load;
if (load->isAtomic && load->signed_) {
if (load->isAtomic() && load->signed_) {
// atomic loads cannot be signed, manually sign it
last = Bits::makeSignExt(load, load->bytes, *module);
load->signed_ = false;
Expand Down
2 changes: 1 addition & 1 deletion src/tools/fuzzing/fuzzing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3239,7 +3239,7 @@ Expression* TranslateToFuzzReader::makeLoad(Type type) {
// make it atomic
auto* load = ret->cast<Load>();
wasm.memories[0]->shared = true;
load->isAtomic = true;
load->order = MemoryOrder::SeqCst;
load->signed_ = false;
load->align = load->bytes;
return load;
Expand Down
4 changes: 2 additions & 2 deletions src/wasm-builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -373,21 +373,21 @@ class Builder {
Type type,
Name memory) {
auto* ret = wasm.allocator.alloc<Load>();
ret->isAtomic = false;
ret->bytes = bytes;
ret->signed_ = signed_;
ret->offset = offset;
ret->align = align;
ret->ptr = ptr;
ret->type = type;
ret->memory = memory;
ret->order = MemoryOrder::Unordered;
ret->finalize();
return ret;
}
Load* makeAtomicLoad(
unsigned bytes, Address offset, Expression* ptr, Type type, Name memory) {
Load* load = makeLoad(bytes, false, offset, bytes, ptr, type, memory);
load->isAtomic = true;
load->order = MemoryOrder::SeqCst;
return load;
}
AtomicWait* makeAtomicWait(Expression* ptr,
Expand Down
2 changes: 1 addition & 1 deletion src/wasm-delegations-fields.def
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ DELEGATE_FIELD_INT(Load, bytes)
DELEGATE_FIELD_INT(Load, signed_)
DELEGATE_FIELD_ADDRESS(Load, offset)
DELEGATE_FIELD_ADDRESS(Load, align)
DELEGATE_FIELD_INT(Load, isAtomic)
DELEGATE_FIELD_INT(Load, order)
DELEGATE_FIELD_NAME_KIND(Load, memory, ModuleItemKind::Memory)
DELEGATE_FIELD_CASE_END(Load)

Expand Down
6 changes: 3 additions & 3 deletions src/wasm-interpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -3862,7 +3862,7 @@ class ModuleRunnerBase : public ExpressionRunner<SubType> {
auto memorySize = info.instance->getMemorySize(info.name);
auto addr =
info.instance->getFinalAddress(curr, flow.getSingleValue(), memorySize);
if (curr->isAtomic) {
if (curr->isAtomic()) {
info.instance->checkAtomicAddress(addr, curr->bytes, memorySize);
}
auto ret = info.interface()->load(curr, addr, info.name);
Expand Down Expand Up @@ -3995,7 +3995,7 @@ class ModuleRunnerBase : public ExpressionRunner<SubType> {
load.signed_ = false;
load.offset = curr->offset;
load.align = curr->align;
load.isAtomic = false;
load.order = MemoryOrder::Unordered;
load.ptr = curr->ptr;
Literal (Literal::*splat)() const = nullptr;
switch (curr->op) {
Expand Down Expand Up @@ -5023,7 +5023,7 @@ class ModuleRunnerBase : public ExpressionRunner<SubType> {
// always an unsigned extension.
load.signed_ = false;
load.align = bytes;
load.isAtomic = true; // understatement
load.order = MemoryOrder::SeqCst;
load.ptr = &ptr;
load.type = type;
load.memory = memoryName;
Expand Down
5 changes: 4 additions & 1 deletion src/wasm.h
Original file line number Diff line number Diff line change
Expand Up @@ -993,9 +993,11 @@ class Load : public SpecificExpression<Expression::LoadId> {
bool signed_ = false;
Address offset;
Address align;
bool isAtomic;
Expression* ptr;
Name memory;
MemoryOrder order;

bool isAtomic() const { return order != MemoryOrder::Unordered; }

// type must be set during creation, cannot be inferred

Expand Down Expand Up @@ -2664,6 +2666,7 @@ std::ostream& operator<<(std::ostream& o, wasm::ModuleExpression pair);
std::ostream& operator<<(std::ostream& o, wasm::ShallowExpression expression);
std::ostream& operator<<(std::ostream& o, wasm::ModuleType pair);
std::ostream& operator<<(std::ostream& o, wasm::ModuleHeapType pair);
std::ostream& operator<<(std::ostream& os, wasm::MemoryOrder mo);

} // namespace std

Expand Down
2 changes: 1 addition & 1 deletion src/wasm/wasm-stack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ void BinaryInstWriter::visitGlobalSet(GlobalSet* curr) {
}

void BinaryInstWriter::visitLoad(Load* curr) {
if (!curr->isAtomic) {
if (!curr->isAtomic()) {
switch (curr->type.getBasic()) {
case Type::i32: {
switch (curr->bytes) {
Expand Down
7 changes: 4 additions & 3 deletions src/wasm/wasm-validator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1095,7 +1095,7 @@ void FunctionValidator::visitGlobalSet(GlobalSet* curr) {
void FunctionValidator::visitLoad(Load* curr) {
auto* memory = getModule()->getMemoryOrNull(curr->memory);
shouldBeTrue(!!memory, curr, "memory.load memory must exist");
if (curr->isAtomic) {
if (curr->isAtomic()) {
shouldBeTrue(getModule()->features.hasAtomics(),
curr,
"Atomic operations require threads [--enable-threads]");
Expand All @@ -1111,13 +1111,14 @@ void FunctionValidator::visitLoad(Load* curr) {
}
validateMemBytes(curr->bytes, curr->type, curr);
validateOffset(curr->offset, memory, curr);
validateAlignment(curr->align, curr->type, curr->bytes, curr->isAtomic, curr);
validateAlignment(
curr->align, curr->type, curr->bytes, curr->isAtomic(), curr);
shouldBeEqualOrFirstIsUnreachable(
curr->ptr->type,
memory->addressType,
curr,
"load pointer type must match memory index type");
if (curr->isAtomic) {
if (curr->isAtomic()) {
shouldBeFalse(curr->signed_, curr, "atomic loads must be unsigned");
shouldBeIntOrUnreachable(
curr->type, curr, "atomic loads must be of integers");
Expand Down
19 changes: 19 additions & 0 deletions src/wasm/wasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2015,3 +2015,22 @@ void Module::clearDebugInfo() {
}

} // namespace wasm

namespace std {

std::ostream& operator<<(std::ostream& os, wasm::MemoryOrder mo) {
switch (mo) {
case wasm::MemoryOrder::Unordered:
os << "Unordered";
break;
case wasm::MemoryOrder::SeqCst:
os << "SeqCst";
break;
case wasm::MemoryOrder::AcqRel:
os << "AcqRel";
break;
}
return os;
}

} // namespace std
2 changes: 1 addition & 1 deletion src/wasm2js.h
Original file line number Diff line number Diff line change
Expand Up @@ -1468,7 +1468,7 @@ Ref Wasm2JSBuilder::processExpression(Expression* curr,
Fatal() << "Unhandled type in load: " << curr->type;
}
}
if (curr->isAtomic) {
if (curr->isAtomic()) {
Ref call = ValueBuilder::makeCall(
ValueBuilder::makeDot(ValueBuilder::makeName(ATOMICS), LOAD));
ValueBuilder::appendToCall(call, ret[1]);
Expand Down
Loading