blob: 2c1091c3c90dbc7fe89005c8855abb8515848efc [file] [log] [blame]
Nicolas Geoffray68a5fef2014-02-18 16:43:35 +00001/*
2 *
3 * Copyright (C) 2014 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18#include "dex_instruction.h"
19#include "builder.h"
20#include "nodes.h"
21
22namespace art {
23
24HGraph* HGraphBuilder::BuildGraph(const uint16_t* code_ptr, const uint16_t* code_end) {
25 graph_ = new (arena_) HGraph(arena_);
26
27 entry_block_ = new (arena_) HBasicBlock(graph_);
28 graph_->AddBlock(entry_block_);
29
30 exit_block_ = new (arena_) HBasicBlock(graph_);
31 // The exit block is added at the end of this method to ensure
32 // its id is the greatest. This is needed for dominator computation.
33
34 entry_block_->AddInstruction(new (arena_) HGoto(entry_block_));
35
36 current_block_ = new (arena_) HBasicBlock(graph_);
37 graph_->AddBlock(current_block_);
38 entry_block_->AddSuccessor(current_block_);
39
40 while (code_ptr < code_end) {
41 const Instruction& instruction = *Instruction::At(code_ptr);
42 if (!AnalyzeDexInstruction(instruction)) return nullptr;
43 code_ptr += instruction.SizeInCodeUnits();
44 }
45
46 exit_block_->AddInstruction(new (arena_) HExit(exit_block_));
47 graph_->AddBlock(exit_block_);
48 return graph_;
49}
50
51bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction) {
52 switch (instruction.Opcode()) {
53 case Instruction::RETURN_VOID:
54 current_block_->AddInstruction(new (arena_) HReturnVoid(current_block_));
55 current_block_->AddSuccessor(exit_block_);
56 current_block_ = nullptr;
57 break;
58 default:
59 return false;
60 }
61 return true;
62}
63
64} // namespace art