1 /*
2 * Copyright 2017 WebAssembly Community Group participants
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #ifndef wasm_ir_block_h
18 #define wasm_ir_block_h
19
20 #include "ir/branch-utils.h"
21 #include "ir/effects.h"
22 #include "ir/manipulation.h"
23 #include "literal.h"
24 #include "wasm-builder.h"
25 #include "wasm.h"
26
27 namespace wasm {
28
29 namespace BlockUtils {
30 // if a block has just one element, it can often be replaced
31 // with that content
32 template<typename T>
33 inline Expression*
34 simplifyToContents(Block* block, T* parent, bool allowTypeChange = false) {
35 auto& list = block->list;
36 if (list.size() == 1 &&
37 !BranchUtils::BranchSeeker::has(list[0], block->name)) {
38 // just one element. try to replace the block
39 auto* singleton = list[0];
40 auto sideEffects = EffectAnalyzer(parent->getPassOptions(),
41 parent->getModule()->features,
42 singleton)
43 .hasSideEffects();
44 if (!sideEffects && !singleton->type.isConcrete()) {
45 // no side effects, and singleton is not returning a value, so we can
46 // throw away the block and its contents, basically
47 return Builder(*parent->getModule()).replaceWithIdenticalType(block);
48 } else if (Type::isSubType(singleton->type, block->type) ||
49 allowTypeChange) {
50 return singleton;
51 } else {
52 // (side effects +) type change, must be block with declared value but
53 // inside is unreachable (if both concrete, must match, and since no name
54 // on block, we can't be branched to, so if singleton is unreachable, so
55 // is the block)
56 assert(block->type.isConcrete() && singleton->type == Type::unreachable);
57 // we could replace with unreachable, but would need to update all
58 // the parent's types
59 }
60 } else if (list.size() == 0) {
61 ExpressionManipulator::nop(block);
62 }
63 return block;
64 }
65
66 // similar, but when we allow the type to change while doing so
67 template<typename T>
simplifyToContentsWithPossibleTypeChange(Block * block,T * parent)68 inline Expression* simplifyToContentsWithPossibleTypeChange(Block* block,
69 T* parent) {
70 return simplifyToContents(block, parent, true);
71 }
72 } // namespace BlockUtils
73
74 } // namespace wasm
75
76 #endif // wasm_ir_block_h
77