Adding control flow simplification pass to compensate for lack of phi.
This commit is contained in:
@@ -11,8 +11,9 @@
|
||||
#define ALLOY_COMPILER_COMPILER_PASSES_H_
|
||||
|
||||
#include <alloy/compiler/passes/constant_propagation_pass.h>
|
||||
#include <alloy/compiler/passes/control_flow_analysis_pass.h>
|
||||
#include <alloy/compiler/passes/context_promotion_pass.h>
|
||||
#include <alloy/compiler/passes/control_flow_analysis_pass.h>
|
||||
#include <alloy/compiler/passes/control_flow_simplification_pass.h>
|
||||
#include <alloy/compiler/passes/data_flow_analysis_pass.h>
|
||||
#include <alloy/compiler/passes/dead_code_elimination_pass.h>
|
||||
//#include <alloy/compiler/passes/dead_store_elimination_pass.h>
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2014 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <alloy/compiler/passes/control_flow_simplification_pass.h>
|
||||
|
||||
#include <alloy/backend/backend.h>
|
||||
#include <alloy/compiler/compiler.h>
|
||||
#include <alloy/runtime/runtime.h>
|
||||
|
||||
namespace alloy {
|
||||
namespace compiler {
|
||||
namespace passes {
|
||||
|
||||
// TODO(benvanik): remove when enums redefined.
|
||||
using namespace alloy::hir;
|
||||
|
||||
using alloy::hir::Edge;
|
||||
using alloy::hir::HIRBuilder;
|
||||
|
||||
ControlFlowSimplificationPass::ControlFlowSimplificationPass()
|
||||
: CompilerPass() {}
|
||||
|
||||
ControlFlowSimplificationPass::~ControlFlowSimplificationPass() {}
|
||||
|
||||
int ControlFlowSimplificationPass::Run(HIRBuilder* builder) {
|
||||
SCOPE_profile_cpu_f("alloy");
|
||||
|
||||
// Walk backwards and merge blocks if possible.
|
||||
bool merged_any = false;
|
||||
auto block = builder->last_block();
|
||||
while (block) {
|
||||
auto prev_block = block->prev;
|
||||
const uint32_t expected = Edge::DOMINATES | Edge::UNCONDITIONAL;
|
||||
if (block->incoming_edge_head &&
|
||||
(block->incoming_edge_head->flags & expected) == expected) {
|
||||
// Dominated by the incoming block.
|
||||
// If that block comes immediately before us then we can merge the
|
||||
// two blocks (assuming it's not a volatile instruction like Trap).
|
||||
if (block->prev == block->incoming_edge_head->src &&
|
||||
block->prev->instr_tail &&
|
||||
!(block->prev->instr_tail->opcode->flags & OPCODE_FLAG_VOLATILE)) {
|
||||
builder->MergeAdjacentBlocks(block->prev, block);
|
||||
merged_any = true;
|
||||
}
|
||||
}
|
||||
block = prev_block;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace passes
|
||||
} // namespace compiler
|
||||
} // namespace alloy
|
||||
33
src/alloy/compiler/passes/control_flow_simplification_pass.h
Normal file
33
src/alloy/compiler/passes/control_flow_simplification_pass.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2014 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef ALLOY_COMPILER_PASSES_CONTROL_FLOW_SIMPLIFICATION_PASS_H_
|
||||
#define ALLOY_COMPILER_PASSES_CONTROL_FLOW_SIMPLIFICATION_PASS_H_
|
||||
|
||||
#include <alloy/compiler/compiler_pass.h>
|
||||
|
||||
namespace alloy {
|
||||
namespace compiler {
|
||||
namespace passes {
|
||||
|
||||
class ControlFlowSimplificationPass : public CompilerPass {
|
||||
public:
|
||||
ControlFlowSimplificationPass();
|
||||
~ControlFlowSimplificationPass() override;
|
||||
|
||||
int Run(hir::HIRBuilder* builder) override;
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
} // namespace passes
|
||||
} // namespace compiler
|
||||
} // namespace alloy
|
||||
|
||||
#endif // ALLOY_COMPILER_PASSES_CONTROL_FLOW_SIMPLIFICATION_PASS_H_
|
||||
@@ -320,8 +320,7 @@ bool RegisterAllocationPass::TryAllocateRegister(Value* value) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RegisterAllocationPass::SpillOneRegister(HIRBuilder* builder,
|
||||
Block* block,
|
||||
bool RegisterAllocationPass::SpillOneRegister(HIRBuilder* builder, Block* block,
|
||||
TypeName required_type) {
|
||||
// Get the set that we will be picking from.
|
||||
RegisterSetUsage* usage_set;
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
'context_promotion_pass.h',
|
||||
'control_flow_analysis_pass.cc',
|
||||
'control_flow_analysis_pass.h',
|
||||
'control_flow_simplification_pass.cc',
|
||||
'control_flow_simplification_pass.h',
|
||||
'data_flow_analysis_pass.cc',
|
||||
'data_flow_analysis_pass.h',
|
||||
'dead_code_elimination_pass.cc',
|
||||
|
||||
Reference in New Issue
Block a user