From 740475d5f45b8caa2c3c6fc51e657ecf4f3547e5 Mon Sep 17 00:00:00 2001 From: Nicolas Geoffray Date: Mon, 29 Sep 2014 10:33:25 +0100 Subject: Fix a bug in the insertion of parallel move. To make sure we do not connect interval siblings in the same parallel move, I added a new field in MoveOperands that tells for which instruction this move is for. A parallel move should not contains moves for the same instructions. The checks revealed a bug when connecting siblings, where we would choose the wrong parallel move. Change-Id: I70f27ec120886745c187071453c78da4c47c1dd2 --- compiler/optimizing/nodes.h | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) (limited to 'compiler/optimizing/nodes.h') diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index 944e80365f..3d65366c43 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -1814,8 +1814,8 @@ class HSuspendCheck : public HTemplateInstruction<0> { class MoveOperands : public ArenaObject { public: - MoveOperands(Location source, Location destination) - : source_(source), destination_(destination) {} + MoveOperands(Location source, Location destination, HInstruction* instruction) + : source_(source), destination_(destination), instruction_(instruction) {} Location GetSource() const { return source_; } Location GetDestination() const { return destination_; } @@ -1863,9 +1863,16 @@ class MoveOperands : public ArenaObject { return source_.IsInvalid(); } + HInstruction* GetInstruction() const { return instruction_; } + private: Location source_; Location destination_; + // The instruction this move is assocatied with. Null when this move is + // for moving an input in the expected locations of user (including a phi user). + // This is only used in debug mode, to ensure we do not connect interval siblings + // in the same parallel move. + HInstruction* instruction_; DISALLOW_COPY_AND_ASSIGN(MoveOperands); }; @@ -1878,6 +1885,12 @@ class HParallelMove : public HTemplateInstruction<0> { : HTemplateInstruction(SideEffects::None()), moves_(arena, kDefaultNumberOfMoves) {} void AddMove(MoveOperands* move) { + if (kIsDebugBuild && move->GetInstruction() != nullptr) { + for (size_t i = 0, e = moves_.Size(); i < e; ++i) { + DCHECK_NE(moves_.Get(i)->GetInstruction(), move->GetInstruction()) + << "Doing parallel moves for the same instruction."; + } + } moves_.Add(move); } -- cgit v1.2.3-59-g8ed1b