2828// have no side effects.
2929//
3030
31+ #include < vector>
3132#include < wasm.h>
3233#include < pass.h>
3334#include < wasm-builder.h>
@@ -321,84 +322,62 @@ struct DeadCodeElimination : public WalkerPass<PostWalker<DeadCodeElimination>>
321322 }
322323 }
323324
324- void visitSetLocal (SetLocal* curr) {
325- if (isUnreachable (curr->value )) {
326- replaceCurrent (curr->value );
325+ // Append the reachable operands of the current node to a block, and replace
326+ // it with the block
327+ void blockifyReachableOperands (std::vector<Expression*>&& list, WasmType type) {
328+ for (size_t i = 0 ; i < list.size (); ++i) {
329+ auto * elem = list[i];
330+ if (isUnreachable (elem)) {
331+ auto * replacement = elem;
332+ if (i > 0 ) {
333+ auto * block = getModule ()->allocator .alloc <Block>();
334+ for (size_t j = 0 ; j < i; ++j) {
335+ block->list .push_back (drop (list[j]));
336+ }
337+ block->list .push_back (list[i]);
338+ block->finalize (type);
339+ replacement = block;
340+ }
341+ replaceCurrent (replacement);
342+ return ;
343+ }
327344 }
328345 }
329346
347+ void visitSetLocal (SetLocal* curr) {
348+ blockifyReachableOperands ({ curr->value }, curr->type );
349+ }
350+
330351 void visitLoad (Load* curr) {
331- if (isUnreachable (curr->ptr )) {
332- replaceCurrent (curr->ptr );
333- }
352+ blockifyReachableOperands ({ curr->ptr }, curr->type );
334353 }
335354
336355 void visitStore (Store* curr) {
337- if (isUnreachable (curr->ptr )) {
338- replaceCurrent (curr->ptr );
339- return ;
340- }
341- if (isUnreachable (curr->value )) {
342- auto * block = getModule ()->allocator .alloc <Block>();
343- block->list .resize (2 );
344- block->list [0 ] = drop (curr->ptr );
345- block->list [1 ] = curr->value ;
346- block->finalize (curr->type );
347- replaceCurrent (block);
348- }
356+ blockifyReachableOperands ({ curr->ptr , curr->value }, curr->type );
357+ }
358+
359+ void visitAtomicRMW (AtomicRMW* curr) {
360+ blockifyReachableOperands ({ curr->ptr , curr->value }, curr->type );
361+ }
362+
363+ void visitAtomicCmpxchg (AtomicCmpxchg* curr) {
364+ blockifyReachableOperands ({ curr->ptr , curr->expected , curr->replacement }, curr->type );
349365 }
350366
351367 void visitUnary (Unary* curr) {
352- if (isUnreachable (curr->value )) {
353- replaceCurrent (curr->value );
354- }
368+ blockifyReachableOperands ({ curr->value }, curr->type );
355369 }
356370
357371 void visitBinary (Binary* curr) {
358- if (isUnreachable (curr->left )) {
359- replaceCurrent (curr->left );
360- return ;
361- }
362- if (isUnreachable (curr->right )) {
363- auto * block = getModule ()->allocator .alloc <Block>();
364- block->list .resize (2 );
365- block->list [0 ] = drop (curr->left );
366- block->list [1 ] = curr->right ;
367- block->finalize (curr->type );
368- replaceCurrent (block);
369- }
372+ blockifyReachableOperands ({ curr->left , curr->right }, curr->type );
370373 }
371374
372375 void visitSelect (Select* curr) {
373- if (isUnreachable (curr->ifTrue )) {
374- replaceCurrent (curr->ifTrue );
375- return ;
376- }
377- if (isUnreachable (curr->ifFalse )) {
378- auto * block = getModule ()->allocator .alloc <Block>();
379- block->list .resize (2 );
380- block->list [0 ] = drop (curr->ifTrue );
381- block->list [1 ] = curr->ifFalse ;
382- block->finalize (curr->type );
383- replaceCurrent (block);
384- return ;
385- }
386- if (isUnreachable (curr->condition )) {
387- auto * block = getModule ()->allocator .alloc <Block>();
388- block->list .resize (3 );
389- block->list [0 ] = drop (curr->ifTrue );
390- block->list [1 ] = drop (curr->ifFalse );
391- block->list [2 ] = curr->condition ;
392- block->finalize (curr->type );
393- replaceCurrent (block);
394- return ;
395- }
376+ blockifyReachableOperands ({ curr->ifTrue , curr->ifFalse , curr->condition }, curr->type );
396377 }
397378
398379 void visitDrop (Drop* curr) {
399- if (isUnreachable (curr->value )) {
400- replaceCurrent (curr->value );
401- }
380+ blockifyReachableOperands ({ curr->value }, curr->type );
402381 }
403382
404383 void visitHost (Host* curr) {
@@ -415,4 +394,3 @@ Pass *createDeadCodeEliminationPass() {
415394}
416395
417396} // namespace wasm
418-
0 commit comments