Fix some bugs in graph construction/simplification methods.
Also fix a brano during SSA construction. The code should
not have been commented out. Added a test to cover what the code
intends.
Change-Id: Ia00ae79dcf75eb0d412f07649d73e7f94dbfb6f0
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index b1c8016..68848de 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -283,18 +283,16 @@
block->predecessors_.Add(this);
}
- void RemovePredecessor(HBasicBlock* block, bool remove_in_successor = true) {
- predecessors_.Delete(block);
- if (remove_in_successor) {
- block->successors_.Delete(this);
- }
+ void ReplaceSuccessor(HBasicBlock* existing, HBasicBlock* new_block) {
+ size_t successor_index = GetSuccessorIndexOf(existing);
+ DCHECK_NE(successor_index, static_cast<size_t>(-1));
+ existing->RemovePredecessor(this);
+ new_block->predecessors_.Add(this);
+ successors_.Put(successor_index, new_block);
}
- void RemoveSuccessor(HBasicBlock* block, bool remove_in_predecessor = true) {
- successors_.Delete(block);
- if (remove_in_predecessor) {
- block->predecessors_.Delete(this);
- }
+ void RemovePredecessor(HBasicBlock* block) {
+ predecessors_.Delete(block);
}
void ClearAllPredecessors() {
@@ -315,6 +313,15 @@
return -1;
}
+ size_t GetSuccessorIndexOf(HBasicBlock* successor) {
+ for (size_t i = 0, e = successors_.Size(); i < e; ++i) {
+ if (successors_.Get(i) == successor) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
void AddInstruction(HInstruction* instruction);
void RemoveInstruction(HInstruction* instruction);
void InsertInstructionBefore(HInstruction* instruction, HInstruction* cursor);
@@ -455,6 +462,7 @@
virtual void SetRawInputAt(size_t index, HInstruction* input) = 0;
virtual bool NeedsEnvironment() const { return false; }
+ virtual bool IsControlFlow() const { return false; }
void AddUseAt(HInstruction* user, size_t index) {
uses_ = new (block_->GetGraph()->GetArena()) HUseListNode<HInstruction>(user, index, uses_);
@@ -733,7 +741,9 @@
// instruction that branches to the exit block.
class HReturnVoid : public HTemplateInstruction<0> {
public:
- HReturnVoid() { }
+ HReturnVoid() {}
+
+ virtual bool IsControlFlow() const { return true; }
DECLARE_INSTRUCTION(ReturnVoid);
@@ -749,6 +759,8 @@
SetRawInputAt(0, value);
}
+ virtual bool IsControlFlow() const { return true; }
+
DECLARE_INSTRUCTION(Return);
private:
@@ -760,7 +772,9 @@
// exit block.
class HExit : public HTemplateInstruction<0> {
public:
- HExit() { }
+ HExit() {}
+
+ virtual bool IsControlFlow() const { return true; }
DECLARE_INSTRUCTION(Exit);
@@ -771,12 +785,14 @@
// Jumps from one block to another.
class HGoto : public HTemplateInstruction<0> {
public:
- HGoto() { }
+ HGoto() {}
HBasicBlock* GetSuccessor() const {
return GetBlock()->GetSuccessors().Get(0);
}
+ virtual bool IsControlFlow() const { return true; }
+
DECLARE_INSTRUCTION(Goto);
private:
@@ -799,6 +815,8 @@
return GetBlock()->GetSuccessors().Get(1);
}
+ virtual bool IsControlFlow() const { return true; }
+
DECLARE_INSTRUCTION(If);
private: