Coverage for /Syzygy/block_graph/analysis/liveness_analysis_unittest.cc

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
99.8%106510670.C++test

Line-by-line coverage:

   1    :  // Copyright 2013 Google Inc. All Rights Reserved.
   2    :  //
   3    :  // Licensed under the Apache License, Version 2.0 (the "License");
   4    :  // you may not use this file except in compliance with the License.
   5    :  // You may obtain a copy of the License at
   6    :  //
   7    :  //     http://www.apache.org/licenses/LICENSE-2.0
   8    :  //
   9    :  // Unless required by applicable law or agreed to in writing, software
  10    :  // distributed under the License is distributed on an "AS IS" BASIS,
  11    :  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12    :  // See the License for the specific language governing permissions and
  13    :  // limitations under the License.
  14    :  //
  15    :  // Unittests for liveness analysis.
  16    :  
  17    :  #include "syzygy/block_graph/analysis/liveness_analysis.h"
  18    :  
  19    :  #include "base/bind.h"
  20    :  #include "gmock/gmock.h"
  21    :  #include "gtest/gtest.h"
  22    :  #include "syzygy/block_graph/basic_block_assembler.h"
  23    :  #include "syzygy/block_graph/analysis/liveness_analysis_internal.h"
  24    :  
  25    :  #include "mnemonics.h"  // NOLINT
  26    :  
  27    :  namespace block_graph {
  28    :  namespace analysis {
  29    :  
  30    :  namespace {
  31    :  
  32    :  typedef BasicBlockSubGraph::BBCollection BBCollection;
  33    :  typedef block_graph::analysis::LivenessAnalysis::State State;
  34    :  typedef block_graph::analysis::LivenessAnalysis::StateHelper StateHelper;
  35    :  typedef block_graph::BasicBlockSubGraph::BasicBlock BasicBlock;
  36    :  typedef block_graph::BasicBlockSubGraph::BasicBlock::Instructions Instructions;
  37    :  typedef block_graph::BasicBlockSubGraph::BasicBlock::Successors Successors;
  38    :  typedef block_graph::BasicBlockSubGraph::BasicCodeBlock BasicCodeBlock;
  39    :  typedef block_graph::BasicBlockSubGraph::BlockDescription BlockDescription;
  40    :  
  41    :  // _asm mov eax, 0
  42    :  const uint8 kMovEaxZero[5] = { 0xB8, 0x00, 0x00, 0x00, 0x00 };
  43    :  // _asm mov ebx, 0
  44    :  const uint8 kMovEbxZero[5] = { 0xBB, 0x00, 0x00, 0x00, 0x00 };
  45    :  // _asm mov ecx, 0
  46    :  const uint8 kMovEcxZero[5] = { 0xB9, 0x00, 0x00, 0x00, 0x00 };
  47    :  // _asm mov edx, 0
  48    :  const uint8 kMovEdxZero[5] = { 0xBA, 0x00, 0x00, 0x00, 0x00 };
  49    :  // _asm mov esi, 0
  50    :  const uint8 kMovEsiZero[5] = { 0xBE, 0x00, 0x00, 0x00, 0x00 };
  51    :  // _asm mov edi, 0
  52    :  const uint8 kMovEdiZero[5] = { 0xBF, 0x00, 0x00, 0x00, 0x00 };
  53    :  // _asm mov esp, 0
  54    :  const uint8 kMovEspZero[5] = { 0xBC, 0x00, 0x00, 0x00, 0x00 };
  55    :  // _asm mov ebp, 0
  56    :  const uint8 kMovEbpZero[5] = { 0xBD, 0x00, 0x00, 0x00, 0x00 };
  57    :  // _asm cmp eax, ebx
  58    :  const uint8 kCmpEaxEbx[2] = { 0x3B, 0xC3 };
  59    :  // _asm mov ax, 0
  60    :  const uint8 kMovAxZero[4] = { 0x66, 0xB8, 0x00, 0x00 };
  61    :  // _asm mov al, 0
  62    :  const uint8 kMovAlZero[2] =  { 0xB0, 0x00 };
  63    :  
  64    :  class LivenessAnalysisTest : public testing::Test {
  65    :   public:
  66    :    LivenessAnalysisTest();
  67    :  
  68  E :    inline bool is_def(const assm::Register& reg) const {
  69  E :      return defs_.IsLive(reg);
  70  E :    }
  71    :  
  72  E :    inline bool is_use(const assm::Register& reg) const {
  73  E :      return uses_.IsLive(reg);
  74  E :    }
  75    :  
  76  E :    inline bool is_live(const assm::Register& reg) const {
  77  E :      return state_.IsLive(reg);
  78  E :    }
  79    :  
  80  E :    inline bool are_arithmetic_flags_live() const {
  81  E :      return state_.AreArithmeticFlagsLive();
  82  E :    }
  83    :  
  84    :    template<size_t N>
  85    :    void AddInstructionFromBuffer(const uint8 (& data)[N]);
  86    :    void DefineAllRegisters();
  87    :    void AnalyzeInstructionsWithoutReset();
  88    :    void AnalyzeInstructions();
  89    :  
  90    :    template<size_t N>
  91    :    void UpdateDefsUsesFromBuffer(const uint8 (& data)[N]);
  92    :  
  93    :    template<size_t N>
  94    :    void AnalyzeSingleInstructionFromBuffer(const uint8 (& data)[N]);
  95    :  
  96    :    bool CheckCarryFlagInstruction(bool expect_on, bool expect_off);
  97    :  
  98    :    void AddSuccessorBetween(Successor::Condition condition,
  99    :                             BasicCodeBlock* from,
 100    :                             BasicCodeBlock* to);
 101    :  
 102    :   protected:
 103    :    BlockGraph block_graph_;
 104    :    BlockGraph::Block* test_block_;
 105    :    BasicBlock::Instructions instructions_;
 106    :    BasicBlockAssembler asm_;
 107    :    LivenessAnalysis liveness_;
 108    :    LivenessAnalysis::State state_;
 109    :    LivenessAnalysis::State defs_;
 110    :    LivenessAnalysis::State uses_;
 111    :  };
 112    :  
 113    :  LivenessAnalysisTest::LivenessAnalysisTest()
 114    :      : testing::Test(),
 115    :        test_block_(NULL),
 116    :        instructions_(),
 117    :        asm_(instructions_.end(), &instructions_),
 118    :        liveness_(),
 119  E :        state_() {
 120  E :    test_block_ = block_graph_.AddBlock(BlockGraph::CODE_BLOCK, 10, "test block");
 121  E :  }
 122    :  
 123    :  template<size_t N>
 124  E :  void LivenessAnalysisTest::UpdateDefsUsesFromBuffer(const uint8 (& data)[N]) {
 125    :    // Decode an instruction.
 126  E :    DCHECK_GT(assm::kMaxInstructionLength, N);
 127    :  
 128  E :    block_graph::Instruction temp;
 129  E :    ASSERT_TRUE(block_graph::Instruction::FromBuffer(&data[0], N, &temp));
 130    :  
 131    :    // Expect to decode the entire buffer.
 132  E :    ASSERT_TRUE(temp.size() == N);
 133    :  
 134    :    // Analyze the defs/uses of this instruction.
 135  E :    StateHelper::GetDefsOf(temp, &defs_);
 136  E :    StateHelper::GetUsesOf(temp, &uses_);
 137  E :  }
 138    :  
 139    :  template<size_t N>
 140  E :  void LivenessAnalysisTest::AddInstructionFromBuffer(const uint8 (& data)[N]) {
 141    :    // Decode an instruction and append it to basicblock_.
 142  E :    DCHECK_GT(assm::kMaxInstructionLength, N);
 143    :  
 144  E :    block_graph::Instruction temp;
 145  E :    ASSERT_TRUE(block_graph::Instruction::FromBuffer(&data[0], N, &temp));
 146    :  
 147    :    // Expect to decode the entire buffer.
 148  E :    ASSERT_TRUE(temp.size() == N);
 149    :  
 150    :    // Append this instruction to the basic block.
 151  E :    instructions_.push_back(temp);
 152  E :  }
 153    :  
 154  E :  void LivenessAnalysisTest::DefineAllRegisters() {
 155    :    // Inserts instructions into basicblock_ so all registers are defined.
 156  E :    AddInstructionFromBuffer(kMovEaxZero);
 157  E :    AddInstructionFromBuffer(kMovEbxZero);
 158  E :    AddInstructionFromBuffer(kMovEcxZero);
 159  E :    AddInstructionFromBuffer(kMovEdxZero);
 160  E :    AddInstructionFromBuffer(kMovEsiZero);
 161  E :    AddInstructionFromBuffer(kMovEdiZero);
 162  E :    AddInstructionFromBuffer(kMovEspZero);
 163  E :    AddInstructionFromBuffer(kMovEbpZero);
 164    :  
 165    :    // Define arithmetic flags.
 166  E :    AddInstructionFromBuffer(kCmpEaxEbx);
 167  E :  }
 168    :  
 169  E :  void LivenessAnalysisTest::AnalyzeInstructionsWithoutReset() {
 170    :    // Perform a backward liveness analysis on instructions in basicblock_.
 171    :    // Results are kept in 'state_' and may be accessed through IsLive and
 172    :    // AreArithmeticFlagsLive.
 173  E :    Instructions::reverse_iterator instr_iter = instructions_.rbegin();
 174  E :    for (; instr_iter != instructions_.rend(); ++instr_iter) {
 175  E :      const Instruction& instr = *instr_iter;
 176  E :      liveness_.PropagateBackward(instr, &state_);
 177  E :    }
 178  E :  }
 179    :  
 180  E :  void LivenessAnalysisTest::AnalyzeInstructions() {
 181  E :    LivenessAnalysis::StateHelper::SetAll(&state_);
 182  E :    AnalyzeInstructionsWithoutReset();
 183  E :  }
 184    :  
 185    :  template<size_t N>
 186    :  void LivenessAnalysisTest::AnalyzeSingleInstructionFromBuffer(
 187  E :      const uint8 (& data)[N]) {
 188    :    // This function creates a basic block with an instruction under test,
 189    :    // followed by instructions to define all registers and flags. This way, the
 190    :    // analysis may assume everything was dead before the instruction.
 191  E :    instructions_.clear();
 192  E :    StateHelper::SetAll(&state_);
 193    :  
 194  E :    AddInstructionFromBuffer(data);
 195  E :    DefineAllRegisters();
 196  E :    AnalyzeInstructions();
 197    :  
 198    :    // Retrieve defs/uses of this instruction.
 199  E :    UpdateDefsUsesFromBuffer(data);
 200  E :  }
 201    :  
 202    :  bool LivenessAnalysisTest::CheckCarryFlagInstruction(
 203  E :      bool expect_on, bool expect_off) {
 204  E :    LivenessAnalysis::State flags;
 205  E :    StateHelper::Clear(&flags);
 206  E :    StateHelper::SetFlags(static_cast<StateHelper::FlagsMask>(~(D_CF)), &state_);
 207    :  
 208    :    // Try with the carry flag on.
 209  E :    StateHelper::Clear(&state_);
 210  E :    StateHelper::SetFlags(D_CF, &state_);
 211  E :    AnalyzeInstructionsWithoutReset();
 212  E :    StateHelper::Subtract(flags, &state_);
 213  E :    if (are_arithmetic_flags_live() != expect_on)
 214  i :      return false;
 215    :  
 216    :    // Try with the carry flag off.
 217  E :    StateHelper::Clear(&state_);
 218  E :    AnalyzeInstructionsWithoutReset();
 219  E :    StateHelper::Subtract(flags, &state_);
 220  E :    if (are_arithmetic_flags_live() != expect_off)
 221  i :      return false;
 222    :  
 223  E :    return true;
 224  E :  }
 225    :  
 226    :  void LivenessAnalysisTest::AddSuccessorBetween(Successor::Condition condition,
 227    :                                                 BasicCodeBlock* from,
 228  E :                                                 BasicCodeBlock* to) {
 229    :    from->successors().push_back(
 230    :        Successor(condition,
 231    :                  BasicBlockReference(BlockGraph::RELATIVE_REF,
 232    :                                      BlockGraph::Reference::kMaximumSize,
 233    :                                      to),
 234  E :                  0));
 235  E :  }
 236    :  
 237  E :  TEST(LivenessAnalysisStateTest, StateRegisterMaskOperations) {
 238    :    // On creation, a state assumes all registers are alive.
 239  E :    State state_full;
 240    :    EXPECT_TRUE(StateHelper::IsSet(state_full,
 241  E :        static_cast<StateHelper::RegisterMask>(StateHelper::REGBITS_ALL)));
 242  E :    EXPECT_TRUE(StateHelper::IsSet(state_full, StateHelper::REGBITS_AX));
 243    :  
 244    :    // The Clear operation should not keep any register partially defined.
 245  E :    State state_empty;
 246  E :    StateHelper::Clear(&state_empty);
 247    :    EXPECT_FALSE(
 248    :      StateHelper::IsPartiallySet(state_empty,
 249  E :        static_cast<StateHelper::RegisterMask>(StateHelper::REGBITS_ALL)));
 250    :    EXPECT_FALSE(
 251  E :      StateHelper::IsPartiallySet(state_empty, StateHelper::REGBITS_AX));
 252    :  
 253    :    // Test sub-registers definition.
 254  E :    State state_ax;
 255  E :    State state_cx;
 256  E :    StateHelper::Clear(&state_ax);
 257  E :    StateHelper::Clear(&state_cx);
 258  E :    StateHelper::Set(StateHelper::REGBITS_AX, &state_ax);
 259  E :    StateHelper::Set(StateHelper::REGBITS_CX, &state_cx);
 260  E :    EXPECT_TRUE(StateHelper::IsPartiallySet(state_ax, StateHelper::REGBITS_EAX));
 261  E :    EXPECT_TRUE(StateHelper::IsSet(state_ax, StateHelper::REGBITS_AL));
 262  E :    EXPECT_TRUE(StateHelper::IsSet(state_ax, StateHelper::REGBITS_AH));
 263  E :    EXPECT_TRUE(StateHelper::IsSet(state_ax, StateHelper::REGBITS_AX));
 264  E :    EXPECT_TRUE(StateHelper::IsPartiallySet(state_cx, StateHelper::REGBITS_ECX));
 265  E :    EXPECT_TRUE(StateHelper::IsSet(state_cx, StateHelper::REGBITS_CL));
 266  E :    EXPECT_TRUE(StateHelper::IsSet(state_cx, StateHelper::REGBITS_CH));
 267  E :    EXPECT_TRUE(StateHelper::IsSet(state_cx, StateHelper::REGBITS_CX));
 268    :  
 269    :    // Test IsLive operation.
 270  E :    EXPECT_TRUE(state_full.IsLive(assm::eax));
 271  E :    EXPECT_TRUE(state_full.IsLive(assm::ecx));
 272  E :    EXPECT_FALSE(state_empty.IsLive(assm::eax));
 273  E :    EXPECT_FALSE(state_empty.IsLive(assm::ecx));
 274  E :    EXPECT_TRUE(state_ax.IsLive(assm::eax));
 275  E :    EXPECT_FALSE(state_ax.IsLive(assm::ecx));
 276  E :    EXPECT_FALSE(state_cx.IsLive(assm::eax));
 277  E :    EXPECT_TRUE(state_cx.IsLive(assm::ecx));
 278    :  
 279    :    // Test copy constructor.
 280  E :    State state_copy(state_ax);
 281    :    EXPECT_TRUE(
 282  E :      StateHelper::IsPartiallySet(state_copy, StateHelper::REGBITS_EAX));
 283  E :    EXPECT_TRUE(StateHelper::IsSet(state_copy, StateHelper::REGBITS_AL));
 284  E :    EXPECT_TRUE(StateHelper::IsSet(state_copy, StateHelper::REGBITS_AH));
 285  E :    EXPECT_TRUE(StateHelper::IsSet(state_copy, StateHelper::REGBITS_AX));
 286    :  
 287    :    // Test Copy operation.
 288  E :    State state_copy_ax;
 289  E :    StateHelper::Copy(state_ax, &state_copy_ax);
 290    :    EXPECT_TRUE(
 291  E :      StateHelper::IsPartiallySet(state_copy_ax, StateHelper::REGBITS_EAX));
 292  E :    EXPECT_TRUE(StateHelper::IsSet(state_copy_ax, StateHelper::REGBITS_AL));
 293  E :    EXPECT_TRUE(StateHelper::IsSet(state_copy_ax, StateHelper::REGBITS_AH));
 294  E :    EXPECT_TRUE(StateHelper::IsSet(state_copy_ax, StateHelper::REGBITS_AX));
 295    :  
 296    :    // Test Union operation.
 297  E :    State state_merged;
 298  E :    StateHelper::Clear(&state_merged);
 299    :    EXPECT_FALSE(
 300  E :      StateHelper::IsPartiallySet(state_merged, StateHelper::REGBITS_AX));
 301    :    EXPECT_FALSE(
 302  E :      StateHelper::IsPartiallySet(state_merged, StateHelper::REGBITS_CX));
 303  E :    StateHelper::Union(state_ax, &state_merged);
 304    :    EXPECT_TRUE(
 305  E :      StateHelper::IsPartiallySet(state_merged, StateHelper::REGBITS_AX));
 306    :    EXPECT_FALSE(
 307  E :      StateHelper::IsPartiallySet(state_merged, StateHelper::REGBITS_CX));
 308  E :    StateHelper::Union(state_cx, &state_merged);
 309    :    EXPECT_TRUE(
 310  E :      StateHelper::IsPartiallySet(state_merged, StateHelper::REGBITS_AX));
 311    :    EXPECT_TRUE(
 312  E :      StateHelper::IsPartiallySet(state_merged, StateHelper::REGBITS_CX));
 313    :  
 314    :    // Test Subtract operation
 315  E :    StateHelper::Subtract(state_ax, &state_merged);
 316    :    EXPECT_FALSE(
 317  E :      StateHelper::IsPartiallySet(state_merged, StateHelper::REGBITS_AX));
 318    :    EXPECT_TRUE(
 319  E :      StateHelper::IsPartiallySet(state_merged, StateHelper::REGBITS_CX));
 320  E :    StateHelper::Subtract(state_cx, &state_merged);
 321    :    EXPECT_FALSE(
 322  E :      StateHelper::IsPartiallySet(state_merged, StateHelper::REGBITS_AX));
 323    :    EXPECT_FALSE(
 324  E :      StateHelper::IsPartiallySet(state_merged, StateHelper::REGBITS_CX));
 325  E :  }
 326    :  
 327  E :  TEST(LivenessAnalysisStateTest, StateFlagsMaskOperations) {
 328    :    // On creation, a state assumes all flags are alive.
 329  E :    State state_full;
 330  E :    EXPECT_TRUE(state_full.AreArithmeticFlagsLive());
 331    :  
 332    :    // The Clear operation should not keep any flags alive.
 333  E :    State state_empty;
 334  E :    StateHelper::Clear(&state_empty);
 335  E :    EXPECT_FALSE(state_empty.AreArithmeticFlagsLive());
 336    :  
 337    :    // Partially defined flags must be considered alive.
 338  E :    State state_flagA;
 339  E :    State state_flagB;
 340  E :    State state_flagC;
 341  E :    StateHelper::Clear(&state_flagA);
 342  E :    StateHelper::Clear(&state_flagB);
 343  E :    StateHelper::SetFlags(0xF0F0, &state_flagA);
 344  E :    StateHelper::SetFlags(0xFFFF, &state_flagB);
 345    :  
 346  E :    EXPECT_TRUE(state_flagA.AreArithmeticFlagsLive());
 347  E :    EXPECT_TRUE(state_flagB.AreArithmeticFlagsLive());
 348    :  
 349    :    // Test Subtract operation.
 350  E :    State state_flag_ari1;
 351  E :    State state_flag_ari2;
 352  E :    StateHelper::Clear(&state_flag_ari1);
 353  E :    StateHelper::Clear(&state_flag_ari2);
 354  E :    StateHelper::SetFlags(D_ZF | D_SF | D_CF, &state_flag_ari1);
 355  E :    StateHelper::SetFlags(D_OF | D_PF | D_AF, &state_flag_ari2);
 356    :  
 357  E :    EXPECT_TRUE(state_flag_ari1.AreArithmeticFlagsLive());
 358  E :    EXPECT_TRUE(state_flag_ari2.AreArithmeticFlagsLive());
 359    :  
 360  E :    State state_merged;
 361  E :    EXPECT_TRUE(state_merged.AreArithmeticFlagsLive());
 362  E :    StateHelper::Subtract(state_flag_ari1, &state_merged);
 363  E :    EXPECT_TRUE(state_merged.AreArithmeticFlagsLive());
 364  E :    StateHelper::Subtract(state_flag_ari2, &state_merged);
 365  E :    EXPECT_FALSE(state_merged.AreArithmeticFlagsLive());
 366  E :  }
 367    :  
 368  E :  TEST_F(LivenessAnalysisTest, Mov1Analysis) {
 369  E :    asm_.mov(assm::eax, Immediate(10));
 370  E :    asm_.mov(assm::ecx, assm::ebx);
 371  E :    AnalyzeInstructions();
 372  E :    EXPECT_FALSE(is_live(assm::eax));
 373  E :    EXPECT_FALSE(is_live(assm::ax));
 374  E :    EXPECT_FALSE(is_live(assm::ah));
 375  E :    EXPECT_TRUE(is_live(assm::ebx));
 376  E :    EXPECT_TRUE(is_live(assm::bx));
 377  E :    EXPECT_TRUE(is_live(assm::bl));
 378  E :    EXPECT_FALSE(is_live(assm::ecx));
 379  E :  }
 380    :  
 381  E :  TEST_F(LivenessAnalysisTest, Mov2Analysis) {
 382  E :    asm_.mov(assm::eax, assm::ebx);
 383  E :    asm_.mov(assm::edx, Immediate(10));
 384  E :    asm_.mov(assm::ecx, Immediate(test_block_, 0));
 385  E :    AnalyzeInstructions();
 386  E :    EXPECT_FALSE(is_live(assm::eax));
 387  E :    EXPECT_FALSE(is_live(assm::ax));
 388  E :    EXPECT_FALSE(is_live(assm::ah));
 389  E :    EXPECT_TRUE(is_live(assm::ebx));
 390  E :    EXPECT_TRUE(is_live(assm::bx));
 391  E :    EXPECT_TRUE(is_live(assm::bl));
 392  E :    EXPECT_FALSE(is_live(assm::ecx));
 393  E :    EXPECT_FALSE(is_live(assm::edx));
 394  E :  }
 395    :  
 396  E :  TEST_F(LivenessAnalysisTest, DefineAllRegisters) {
 397    :    // Validate the tester by defining all registers and using none.
 398  E :    DefineAllRegisters();
 399  E :    AnalyzeInstructions();
 400  E :    EXPECT_FALSE(is_live(assm::eax));
 401  E :    EXPECT_FALSE(is_live(assm::ax));
 402  E :    EXPECT_FALSE(is_live(assm::al));
 403  E :    EXPECT_FALSE(is_live(assm::ah));
 404  E :    EXPECT_FALSE(is_live(assm::ebx));
 405  E :    EXPECT_FALSE(is_live(assm::bx));
 406  E :    EXPECT_FALSE(is_live(assm::bl));
 407  E :    EXPECT_FALSE(is_live(assm::bh));
 408  E :    EXPECT_FALSE(is_live(assm::ecx));
 409  E :    EXPECT_FALSE(is_live(assm::cx));
 410  E :    EXPECT_FALSE(is_live(assm::cl));
 411  E :    EXPECT_FALSE(is_live(assm::ch));
 412  E :    EXPECT_FALSE(is_live(assm::edx));
 413  E :    EXPECT_FALSE(is_live(assm::dx));
 414  E :    EXPECT_FALSE(is_live(assm::dl));
 415  E :    EXPECT_FALSE(is_live(assm::dh));
 416  E :    EXPECT_FALSE(is_live(assm::esi));
 417  E :    EXPECT_FALSE(is_live(assm::si));
 418  E :    EXPECT_FALSE(is_live(assm::edi));
 419  E :    EXPECT_FALSE(is_live(assm::di));
 420  E :    EXPECT_FALSE(are_arithmetic_flags_live());
 421  E :  }
 422    :  
 423  E :  TEST_F(LivenessAnalysisTest, Defs1Analysis) {
 424    :    // Validate the tester by defining all registers and using some of them.
 425  E :    AddInstructionFromBuffer(kMovEaxZero);
 426  E :    AddInstructionFromBuffer(kMovEcxZero);
 427  E :    AddInstructionFromBuffer(kMovEsiZero);
 428  E :    AnalyzeInstructions();
 429  E :    EXPECT_FALSE(is_live(assm::eax));
 430  E :    EXPECT_FALSE(is_live(assm::ax));
 431  E :    EXPECT_FALSE(is_live(assm::ah));
 432  E :    EXPECT_TRUE(is_live(assm::ebx));
 433  E :    EXPECT_TRUE(is_live(assm::bx));
 434  E :    EXPECT_TRUE(is_live(assm::bl));
 435  E :    EXPECT_FALSE(is_live(assm::ecx));
 436  E :    EXPECT_FALSE(is_live(assm::cx));
 437  E :    EXPECT_FALSE(is_live(assm::cl));
 438  E :    EXPECT_TRUE(is_live(assm::edx));
 439  E :    EXPECT_TRUE(is_live(assm::dx));
 440  E :    EXPECT_TRUE(is_live(assm::dl));
 441  E :    EXPECT_FALSE(is_live(assm::esi));
 442  E :    EXPECT_FALSE(is_live(assm::si));
 443  E :    EXPECT_TRUE(is_live(assm::edi));
 444  E :    EXPECT_TRUE(is_live(assm::di));
 445  E :  }
 446    :  
 447  E :  TEST_F(LivenessAnalysisTest, Defs2Analysis) {
 448    :    // Validate the tester by defining all registers and using some of them.
 449  E :    AddInstructionFromBuffer(kMovEbxZero);
 450  E :    AddInstructionFromBuffer(kMovEdxZero);
 451  E :    AddInstructionFromBuffer(kMovEdiZero);
 452  E :    AnalyzeInstructions();
 453  E :    EXPECT_TRUE(is_live(assm::eax));
 454  E :    EXPECT_TRUE(is_live(assm::ax));
 455  E :    EXPECT_TRUE(is_live(assm::al));
 456  E :    EXPECT_FALSE(is_live(assm::ebx));
 457  E :    EXPECT_FALSE(is_live(assm::bx));
 458  E :    EXPECT_FALSE(is_live(assm::bh));
 459  E :    EXPECT_TRUE(is_live(assm::ecx));
 460  E :    EXPECT_TRUE(is_live(assm::cx));
 461  E :    EXPECT_TRUE(is_live(assm::cl));
 462  E :    EXPECT_FALSE(is_live(assm::edx));
 463  E :    EXPECT_FALSE(is_live(assm::dx));
 464  E :    EXPECT_FALSE(is_live(assm::dl));
 465  E :    EXPECT_TRUE(is_live(assm::esi));
 466  E :    EXPECT_TRUE(is_live(assm::si));
 467  E :    EXPECT_FALSE(is_live(assm::edi));
 468  E :    EXPECT_FALSE(is_live(assm::di));
 469  E :  }
 470    :  
 471  E :  TEST_F(LivenessAnalysisTest, Analysis16Bit) {
 472  E :    AddInstructionFromBuffer(kMovAxZero);
 473  E :    AnalyzeInstructions();
 474  E :    EXPECT_TRUE(is_live(assm::eax));
 475  E :    EXPECT_FALSE(is_live(assm::ax));
 476  E :    EXPECT_FALSE(is_live(assm::al));
 477  E :    EXPECT_FALSE(is_live(assm::ah));
 478  E :  }
 479    :  
 480  E :  TEST_F(LivenessAnalysisTest, Analysis8Bit) {
 481  E :    AddInstructionFromBuffer(kMovAlZero);
 482  E :    AnalyzeInstructions();
 483  E :    EXPECT_TRUE(is_live(assm::eax));
 484  E :    EXPECT_TRUE(is_live(assm::ax));
 485  E :    EXPECT_FALSE(is_live(assm::al));
 486  E :    EXPECT_TRUE(is_live(assm::ah));
 487  E :  }
 488    :  
 489  E :  TEST_F(LivenessAnalysisTest, OperandTypeLeft) {
 490    :    // Validate the support of all DiStorm operand types (as first operand).
 491    :    // _asm add eax, ecx
 492    :    static const uint8 kOpReg1[] = { 0x03, 0xC1 };
 493  E :    AnalyzeSingleInstructionFromBuffer(kOpReg1);
 494  E :    EXPECT_TRUE(is_live(assm::eax));
 495  E :    EXPECT_FALSE(is_live(assm::ebx));
 496  E :    EXPECT_TRUE(is_live(assm::ecx));
 497  E :    EXPECT_FALSE(is_live(assm::edx));
 498    :  
 499    :    // _asm add [eax], ecx
 500    :    static const uint8 kOpSmem[] = { 0x01, 0x08 };
 501  E :    AnalyzeSingleInstructionFromBuffer(kOpSmem);
 502  E :    EXPECT_TRUE(is_live(assm::eax));
 503  E :    EXPECT_FALSE(is_live(assm::ebx));
 504  E :    EXPECT_TRUE(is_live(assm::ecx));
 505  E :    EXPECT_FALSE(is_live(assm::edx));
 506    :  
 507    :    // _asm add [eax + 42], ecx
 508    :    static const uint8 kOpSmemOffet[] = { 0x01, 0x48, 0x2A };
 509  E :    AnalyzeSingleInstructionFromBuffer(kOpSmemOffet);
 510  E :    EXPECT_TRUE(is_live(assm::eax));
 511  E :    EXPECT_FALSE(is_live(assm::ebx));
 512  E :    EXPECT_TRUE(is_live(assm::ecx));
 513  E :    EXPECT_FALSE(is_live(assm::edx));
 514    :  
 515    :    // _asm add [eax + ebx*2 + 42], ecx
 516    :    static const uint8 kOpMemOffset[] = { 0x01, 0x4C, 0x58, 0x2A };
 517  E :    AnalyzeSingleInstructionFromBuffer(kOpMemOffset);
 518  E :    EXPECT_TRUE(is_live(assm::eax));
 519  E :    EXPECT_TRUE(is_live(assm::ebx));
 520  E :    EXPECT_TRUE(is_live(assm::ecx));
 521  E :    EXPECT_FALSE(is_live(assm::edx));
 522    :  
 523    :    // _asm add DWORD PTR [X], ecx
 524    :    static const uint8 kOpDispl[] = { 0x01, 0x0D, 0x80, 0x1E, 0xF2, 0x00 };
 525  E :    AnalyzeSingleInstructionFromBuffer(kOpDispl);
 526  E :    EXPECT_FALSE(is_live(assm::eax));
 527  E :    EXPECT_FALSE(is_live(assm::ebx));
 528  E :    EXPECT_TRUE(is_live(assm::ecx));
 529  E :    EXPECT_FALSE(is_live(assm::edx));
 530  E :  }
 531    :  
 532  E :  TEST_F(LivenessAnalysisTest, OperandTypeRight) {
 533    :    // Validate the support of all DiStorm operand types (as second operand).
 534    :    // _asm add ecx, 1
 535    :    static const uint8 kOpReg1[] = { 0x83, 0xC1, 0x01 };
 536  E :    AnalyzeSingleInstructionFromBuffer(kOpReg1);
 537  E :    EXPECT_FALSE(is_live(assm::eax));
 538  E :    EXPECT_FALSE(is_live(assm::ebx));
 539  E :    EXPECT_TRUE(is_live(assm::ecx));
 540  E :    EXPECT_FALSE(is_live(assm::edx));
 541    :  
 542    :    // _asm add ecx, eax
 543    :    static const uint8 kOpReg2[] = { 0x03, 0xC8 };
 544  E :    AnalyzeSingleInstructionFromBuffer(kOpReg2);
 545  E :    EXPECT_TRUE(is_live(assm::eax));
 546  E :    EXPECT_FALSE(is_live(assm::ebx));
 547  E :    EXPECT_TRUE(is_live(assm::ecx));
 548  E :    EXPECT_FALSE(is_live(assm::edx));
 549    :  
 550    :    // _asm add ecx, [eax]
 551    :    static const uint8 kOpSmem[] = { 0x03, 0x08 };
 552  E :    AnalyzeSingleInstructionFromBuffer(kOpSmem);
 553  E :    EXPECT_TRUE(is_live(assm::eax));
 554  E :    EXPECT_FALSE(is_live(assm::ebx));
 555  E :    EXPECT_TRUE(is_live(assm::ecx));
 556  E :    EXPECT_FALSE(is_live(assm::edx));
 557    :  
 558    :    // _asm add ecx, [eax + 42]
 559    :    static const uint8 kOpSmemOffet[] = { 0x03, 0x48, 0x2A };
 560  E :    AnalyzeSingleInstructionFromBuffer(kOpSmemOffet);
 561  E :    EXPECT_TRUE(is_live(assm::eax));
 562  E :    EXPECT_FALSE(is_live(assm::ebx));
 563  E :    EXPECT_TRUE(is_live(assm::ecx));
 564  E :    EXPECT_FALSE(is_live(assm::edx));
 565    :  
 566    :    // _asm add ecx, [eax + ebx*2 + 42]
 567    :    static const uint8 kOpMemOffset[] = { 0x03, 0x4C, 0x58, 0x2A };
 568  E :    AnalyzeSingleInstructionFromBuffer(kOpMemOffset);
 569  E :    EXPECT_TRUE(is_live(assm::eax));
 570  E :    EXPECT_TRUE(is_live(assm::ebx));
 571  E :    EXPECT_TRUE(is_live(assm::ecx));
 572  E :    EXPECT_FALSE(is_live(assm::edx));
 573    :  
 574    :    // _asm add ecx, DWORD PTR [X]
 575    :    static const uint8 kOpDispl[] = { 0x03, 0x0D, 0x80, 0x1E, 0x27, 0x00 };
 576  E :    AnalyzeSingleInstructionFromBuffer(kOpDispl);
 577  E :    EXPECT_FALSE(is_live(assm::eax));
 578  E :    EXPECT_FALSE(is_live(assm::ebx));
 579  E :    EXPECT_TRUE(is_live(assm::ecx));
 580  E :    EXPECT_FALSE(is_live(assm::edx));
 581  E :  }
 582    :  
 583  E :  TEST_F(LivenessAnalysisTest, InstructionWithoutDefine) {
 584    :    // Validate instructions that fully overwrite and use the destination.
 585    :    // _asm cmp eax, [ecx]
 586    :    static const uint8 kCmp[] = { 0x3B, 0x01 };
 587  E :    AnalyzeSingleInstructionFromBuffer(kCmp);
 588  E :    EXPECT_TRUE(is_live(assm::eax));
 589  E :    EXPECT_TRUE(is_live(assm::ecx));
 590    :  
 591    :    // _asm test ebx, [edx+12]
 592    :    static const uint8 kTest[] = { 0x85, 0x5A, 0x0C };
 593  E :    AnalyzeSingleInstructionFromBuffer(kTest);
 594  E :    EXPECT_TRUE(is_live(assm::ebx));
 595  E :    EXPECT_TRUE(is_live(assm::edx));
 596  E :  }
 597    :  
 598  E :  TEST_F(LivenessAnalysisTest, InstructionsWithDefine) {
 599    :    // Validate instructions that fully overwrite the destination.
 600    :    // _asm mov ebx, [edx+12]
 601    :    static const uint8 kCmp[] = { 0x8B, 0x5A, 0x0C };
 602  E :    AnalyzeSingleInstructionFromBuffer(kCmp);
 603  E :    EXPECT_FALSE(is_live(assm::ebx));
 604  E :    EXPECT_TRUE(is_live(assm::edx));
 605    :  
 606    :    // _asm lea ebx, [edx+12]
 607    :    static const uint8 kTest[] = { 0x8D, 0x5A, 0x0C };
 608  E :    AnalyzeSingleInstructionFromBuffer(kTest);
 609  E :    EXPECT_FALSE(is_live(assm::ebx));
 610  E :    EXPECT_TRUE(is_live(assm::edx));
 611  E :  }
 612    :  
 613  E :  TEST_F(LivenessAnalysisTest, InstructionsWithPartialDefine) {
 614    :    // Registers partially defined must be considered alive.
 615    :    // _asm mov bl, dl
 616    :    static const uint8 kCmp[] = { 0xB3, 0x0C };
 617    :    // _asm mov DWORD PTR [X], ebx
 618    :    static const uint8 kStore[] = { 0x89, 0x1D, 0x80, 0x1E, 0x10, 0x01 };
 619  E :    AddInstructionFromBuffer(kCmp);
 620  E :    AddInstructionFromBuffer(kStore);
 621  E :    AnalyzeInstructions();
 622    :  
 623  E :    EXPECT_TRUE(is_live(assm::ebx));
 624  E :    EXPECT_TRUE(is_live(assm::bx));
 625  E :    EXPECT_FALSE(is_live(assm::bl));
 626  E :    EXPECT_TRUE(is_live(assm::bh));
 627    :  
 628  E :    EXPECT_TRUE(is_live(assm::edx));
 629  E :    EXPECT_TRUE(is_live(assm::dx));
 630  E :    EXPECT_TRUE(is_live(assm::dl));
 631  E :    EXPECT_TRUE(is_live(assm::dh));
 632  E :  }
 633    :  
 634  E :  TEST_F(LivenessAnalysisTest, InstructionsWithPartialDefineAll) {
 635    :    static const uint8 kMovAl[] = { 0xB0, 0x00 };
 636    :    static const uint8 kMovBl[] = { 0xB1, 0x00 };
 637    :    static const uint8 kMovCl[] = { 0xB2, 0x00 };
 638    :    static const uint8 kMovDl[] = { 0xB3, 0x00 };
 639    :    static const uint8 kMovAh[] = { 0xB4, 0x00 };
 640    :    static const uint8 kMovBh[] = { 0xB7, 0x00 };
 641    :    static const uint8 kMovCh[] = { 0xB5, 0x00 };
 642    :    static const uint8 kMovDh[] = { 0xB6, 0x00 };
 643    :    static const uint8 kMovAx[] = { 0x66, 0xB8, 0x00, 0x00 };
 644    :    static const uint8 kMovBx[] = { 0x66, 0xBB, 0x00, 0x00 };
 645    :    static const uint8 kMovCx[] = { 0x66, 0xB9, 0x00, 0x00 };
 646    :    static const uint8 kMovDx[] = { 0x66, 0xBA, 0x00, 0x00 };
 647    :    static const uint8 kMovSi[] = { 0x66, 0xBE, 0x00, 0x00 };
 648    :    static const uint8 kMovDi[] = { 0x66, 0xBF, 0x00, 0x00 };
 649    :    static const uint8 kMovSp[] = { 0x66, 0xBC, 0x00, 0x00 };
 650    :    static const uint8 kMovBp[] = { 0x66, 0xBD, 0x00, 0x00 };
 651    :  
 652    :    // 8-bit partial registers.
 653  E :    AddInstructionFromBuffer(kMovAl);
 654  E :    AddInstructionFromBuffer(kMovBl);
 655  E :    AddInstructionFromBuffer(kMovCl);
 656  E :    AddInstructionFromBuffer(kMovDl);
 657    :  
 658  E :    AddInstructionFromBuffer(kMovAh);
 659  E :    AddInstructionFromBuffer(kMovBh);
 660  E :    AddInstructionFromBuffer(kMovCh);
 661  E :    AddInstructionFromBuffer(kMovDh);
 662    :  
 663    :    // 16-bit partial registers.
 664  E :    AddInstructionFromBuffer(kMovAx);
 665  E :    AddInstructionFromBuffer(kMovBx);
 666  E :    AddInstructionFromBuffer(kMovCx);
 667  E :    AddInstructionFromBuffer(kMovDx);
 668    :  
 669  E :    AddInstructionFromBuffer(kMovSi);
 670  E :    AddInstructionFromBuffer(kMovDi);
 671  E :    AddInstructionFromBuffer(kMovSp);
 672  E :    AddInstructionFromBuffer(kMovBp);
 673    :  
 674  E :    AnalyzeInstructions();
 675    :  
 676  E :    EXPECT_TRUE(is_live(assm::eax));
 677  E :    EXPECT_TRUE(is_live(assm::ecx));
 678  E :    EXPECT_TRUE(is_live(assm::edx));
 679  E :    EXPECT_TRUE(is_live(assm::eax));
 680  E :    EXPECT_TRUE(is_live(assm::esi));
 681  E :    EXPECT_TRUE(is_live(assm::edi));
 682  E :    EXPECT_TRUE(is_live(assm::esp));
 683  E :    EXPECT_TRUE(is_live(assm::ebp));
 684  E :  }
 685    :  
 686  E :  TEST_F(LivenessAnalysisTest, ArithmeticUnaryInstructions) {
 687    :    // _asm dec eax
 688    :    static const uint8 kDec1[] = { 0x48 };
 689  E :    AnalyzeSingleInstructionFromBuffer(kDec1);
 690  E :    EXPECT_TRUE(is_live(assm::eax));
 691    :  
 692    :    // _asm dec [ebx + 1]
 693    :    static const uint8 kDec2[] = { 0xFE, 0x4B, 0x01 };
 694  E :    AnalyzeSingleInstructionFromBuffer(kDec2);
 695  E :    EXPECT_TRUE(is_live(assm::ebx));
 696    :  
 697    :    // _asm dec [esi + ebx*2 + 1]
 698    :    static const uint8 kDec3[] = { 0xFE, 0x4C, 0x5E, 0x01 };
 699  E :    AnalyzeSingleInstructionFromBuffer(kDec3);
 700  E :    EXPECT_TRUE(is_live(assm::esi));
 701  E :    EXPECT_TRUE(is_live(assm::ebx));
 702    :  
 703    :    // _asm dec WORD PTR [X]
 704    :    static const uint8 kDec4[] = { 0x66, 0xFF, 0x0D, 0x80, 0x1E, 0x92, 0x00 };
 705  E :    AnalyzeSingleInstructionFromBuffer(kDec4);
 706  E :    EXPECT_FALSE(is_live(assm::eax));
 707  E :    EXPECT_FALSE(is_live(assm::ebx));
 708  E :    EXPECT_FALSE(is_live(assm::ecx));
 709  E :    EXPECT_FALSE(is_live(assm::edx));
 710    :  
 711    :    // _asm not ebx
 712    :    static const uint8 kNot1[] = { 0xF7, 0xD3 };
 713  E :    AnalyzeSingleInstructionFromBuffer(kNot1);
 714  E :    EXPECT_TRUE(is_live(assm::ebx));
 715    :  
 716    :    // _asm not [ebx]
 717    :    static const uint8 kNot2[] = { 0xF6, 0x13 };
 718  E :    AnalyzeSingleInstructionFromBuffer(kNot2);
 719  E :    EXPECT_TRUE(is_live(assm::ebx));
 720    :  
 721    :    // _asm neg ebx
 722    :    static const uint8 kNeg1[] = { 0xF7, 0xDB };
 723  E :    AnalyzeSingleInstructionFromBuffer(kNeg1);
 724  E :    EXPECT_TRUE(is_live(assm::ebx));
 725    :  
 726    :    // _asm neg [ebx]
 727    :    static const uint8 kNeg2[] = { 0xF6, 0x1B };
 728  E :    AnalyzeSingleInstructionFromBuffer(kNeg2);
 729  E :    EXPECT_TRUE(is_live(assm::ebx));
 730    :  
 731    :    // _asm inc edx
 732    :    static const uint8 kInc[] = { 0x42 };
 733  E :    AnalyzeSingleInstructionFromBuffer(kInc);
 734  E :    EXPECT_TRUE(is_live(assm::edx));
 735    :  
 736    :    // _asm inc dh
 737    :    static const uint8 kIncHalf[] = { 0xFE, 0xC6 };
 738  E :    AnalyzeSingleInstructionFromBuffer(kIncHalf);
 739  E :    EXPECT_TRUE(is_live(assm::edx));
 740  E :    EXPECT_TRUE(is_def(assm::dh));
 741  E :    EXPECT_FALSE(is_def(assm::dl));
 742  E :    EXPECT_TRUE(is_use(assm::dh));
 743  E :    EXPECT_FALSE(is_use(assm::dl));
 744  E :  }
 745    :  
 746  E :  TEST_F(LivenessAnalysisTest, DecIncFlagsInstructions) {
 747    :    // NOTE: inc/dec do not touch the carry flag.
 748    :    // _asm inc edx
 749    :    static const uint8 kInc[] = { 0x42 };
 750  E :    AddInstructionFromBuffer(kInc);
 751  E :    EXPECT_TRUE(CheckCarryFlagInstruction(true, false));
 752  E :    instructions_.clear();
 753    :  
 754    :    // _asm dec eax
 755    :    static const uint8 kDec1[] = { 0x48 };
 756  E :    AddInstructionFromBuffer(kDec1);
 757  E :    EXPECT_TRUE(CheckCarryFlagInstruction(true, false));
 758  E :    instructions_.clear();
 759  E :  }
 760    :  
 761  E :  TEST_F(LivenessAnalysisTest, ArithmeticBinaryInstructions) {
 762    :    // _asm add ebx, ecx
 763    :    static const uint8 kAdd[] = { 0x03, 0xD9 };
 764  E :    AnalyzeSingleInstructionFromBuffer(kAdd);
 765  E :    EXPECT_TRUE(is_live(assm::ebx));
 766  E :    EXPECT_TRUE(is_live(assm::ecx));
 767  E :    EXPECT_TRUE(is_def(assm::ebx));
 768  E :    EXPECT_TRUE(is_use(assm::ebx));
 769  E :    EXPECT_TRUE(is_use(assm::ecx));
 770    :  
 771    :    // _asm adc ebx, edx
 772    :    static const uint8 kAdc[] = { 0x13, 0xDA };
 773  E :    AnalyzeSingleInstructionFromBuffer(kAdc);
 774  E :    EXPECT_TRUE(is_live(assm::ebx));
 775  E :    EXPECT_TRUE(is_live(assm::edx));
 776    :  
 777    :    // _asm sub esi, edi
 778    :    static const uint8 kSub[] = { 0x2B, 0xF7 };
 779  E :    AnalyzeSingleInstructionFromBuffer(kSub);
 780  E :    EXPECT_TRUE(is_live(assm::esi));
 781  E :    EXPECT_TRUE(is_live(assm::edi));
 782    :  
 783    :    // _asm sbb ebx, [eax + edx + 12]
 784    :    static const uint8 KSbb[] = { 0x1B, 0x5C, 0x10, 0x0C };
 785  E :    AnalyzeSingleInstructionFromBuffer(KSbb);
 786  E :    EXPECT_TRUE(is_live(assm::eax));
 787  E :    EXPECT_TRUE(is_live(assm::ebx));
 788  E :    EXPECT_TRUE(is_live(assm::edx));
 789    :  
 790    :    // _asm and ebx, ecx
 791    :    static const uint8 kAnd[] = { 0x23, 0xD9 };
 792  E :    AnalyzeSingleInstructionFromBuffer(kAnd);
 793  E :    EXPECT_TRUE(is_live(assm::ebx));
 794  E :    EXPECT_TRUE(is_live(assm::ecx));
 795    :  
 796    :    // _asm or esi, [edi]
 797    :    static const uint8 kOr[] = { 0x0B, 0x37 };
 798  E :    AnalyzeSingleInstructionFromBuffer(kOr);
 799  E :    EXPECT_TRUE(is_live(assm::esi));
 800  E :    EXPECT_TRUE(is_live(assm::edi));
 801    :  
 802    :    // _asm xor [esi], edi
 803    :    static const uint8 kXor[] = { 0x31, 0x3E };
 804  E :    AnalyzeSingleInstructionFromBuffer(kXor);
 805  E :    EXPECT_TRUE(is_live(assm::esi));
 806  E :    EXPECT_TRUE(is_live(assm::edi));
 807    :  
 808    :    // _asm shl ebx, 1
 809    :    static const uint8 kShl1[] = { 0xD1, 0xE3 };
 810  E :    AnalyzeSingleInstructionFromBuffer(kShl1);
 811  E :    EXPECT_TRUE(is_live(assm::ebx));
 812    :  
 813    :    // _asm shr esi, 2
 814    :    static const uint8 kShr1[] = { 0xC1, 0xEE, 0x02 };
 815  E :    AnalyzeSingleInstructionFromBuffer(kShr1);
 816  E :    EXPECT_TRUE(is_live(assm::esi));
 817    :  
 818    :    // _asm sar ecx, 3
 819    :    static const uint8 kSar1[] = { 0xC1, 0xF9, 0x03 };
 820  E :    AnalyzeSingleInstructionFromBuffer(kSar1);
 821  E :    EXPECT_TRUE(is_live(assm::ecx));
 822    :  
 823    :    // _asm rol ebx, 1
 824    :    static const uint8 kRol1[] = { 0xD1, 0xC3 };
 825  E :    AnalyzeSingleInstructionFromBuffer(kRol1);
 826  E :    EXPECT_TRUE(is_live(assm::ebx));
 827    :  
 828    :    // _asm ror esi, 2
 829    :    static const uint8 kRor1[] = { 0xC1, 0xCE, 0x02 };
 830  E :    AnalyzeSingleInstructionFromBuffer(kRor1);
 831  E :    EXPECT_TRUE(is_live(assm::esi));
 832    :  
 833    :    // _asm shl ebx, cl
 834    :    static const uint8 kShl2[] = { 0xD3, 0xE3 };
 835  E :    AnalyzeSingleInstructionFromBuffer(kShl2);
 836  E :    EXPECT_TRUE(is_live(assm::ebx));
 837  E :    EXPECT_TRUE(is_live(assm::ecx));
 838    :  
 839    :    // _asm shr esi, cl
 840    :    static const uint8 kShr2[] = { 0xD3, 0xEE };
 841  E :    AnalyzeSingleInstructionFromBuffer(kShr2);
 842  E :    EXPECT_TRUE(is_live(assm::esi));
 843  E :    EXPECT_TRUE(is_live(assm::ecx));
 844    :  
 845    :    // _asm sar edx, cl
 846    :    static const uint8 kSar2[] = { 0xD3, 0xFA };
 847  E :    AnalyzeSingleInstructionFromBuffer(kSar2);
 848  E :    EXPECT_TRUE(is_live(assm::edx));
 849  E :    EXPECT_TRUE(is_live(assm::ecx));
 850    :  
 851    :    // _asm rol ebx, cl
 852    :    static const uint8 kRol2[] = { 0xD3, 0xC3 };
 853  E :    AnalyzeSingleInstructionFromBuffer(kRol2);
 854  E :    EXPECT_TRUE(is_live(assm::ebx));
 855  E :    EXPECT_TRUE(is_live(assm::ecx));
 856    :  
 857    :    // _asm ror esi, cl
 858    :    static const uint8 kRor2[] = { 0xD3, 0xCE };
 859  E :    AnalyzeSingleInstructionFromBuffer(kRor2);
 860  E :    EXPECT_TRUE(is_live(assm::esi));
 861  E :    EXPECT_TRUE(is_live(assm::ecx));
 862  E :  }
 863    :  
 864  E :  TEST_F(LivenessAnalysisTest, ArithmeticFlagsInstructions) {
 865    :    // _asm adc ebx, edx
 866    :    static const uint8 kAdc[] = { 0x13, 0xDA };
 867  E :    AnalyzeSingleInstructionFromBuffer(kAdc);
 868  E :    EXPECT_TRUE(CheckCarryFlagInstruction(true, true));
 869    :  
 870    :    // _asm sbb ebx, [eax + edx + 12]
 871    :    static const uint8 KSbb[] = { 0x1B, 0x5C, 0x10, 0x0C };
 872  E :    AnalyzeSingleInstructionFromBuffer(KSbb);
 873  E :    EXPECT_TRUE(CheckCarryFlagInstruction(true, true));
 874  E :  }
 875    :  
 876  E :  TEST_F(LivenessAnalysisTest, MultiplicationInstructions) {
 877    :    // _asm mul ecx
 878    :    static const uint8 kMul32[] = { 0xF7, 0xE1 };
 879  E :    AnalyzeSingleInstructionFromBuffer(kMul32);
 880  E :    EXPECT_FALSE(are_arithmetic_flags_live());
 881  E :    EXPECT_TRUE(is_live(assm::eax));
 882  E :    EXPECT_FALSE(is_live(assm::ebx));
 883  E :    EXPECT_TRUE(is_live(assm::ecx));
 884  E :    EXPECT_FALSE(is_live(assm::edx));
 885  E :    EXPECT_TRUE(is_def(assm::eax));
 886  E :    EXPECT_FALSE(is_def(assm::ecx));
 887  E :    EXPECT_TRUE(is_def(assm::edx));
 888  E :    EXPECT_TRUE(is_use(assm::eax));
 889  E :    EXPECT_TRUE(is_use(assm::ecx));
 890  E :    EXPECT_FALSE(is_use(assm::edx));
 891    :  
 892    :    // _asm mul cx
 893    :    static const uint8 kMul16[] = { 0x66, 0xF7, 0xE1 };
 894  E :    AnalyzeSingleInstructionFromBuffer(kMul16);
 895  E :    EXPECT_FALSE(are_arithmetic_flags_live());
 896  E :    EXPECT_TRUE(is_live(assm::eax));
 897  E :    EXPECT_FALSE(is_live(assm::ebx));
 898  E :    EXPECT_TRUE(is_live(assm::ecx));
 899  E :    EXPECT_FALSE(is_live(assm::edx));
 900  E :    EXPECT_TRUE(is_def(assm::eax));
 901  E :    EXPECT_FALSE(is_def(assm::ecx));
 902  E :    EXPECT_TRUE(is_use(assm::eax));
 903  E :    EXPECT_TRUE(is_use(assm::ecx));
 904    :  
 905    :    // _asm mul cl
 906    :    static const uint8 kMul8[] = { 0xF6, 0xE1 };
 907  E :    AnalyzeSingleInstructionFromBuffer(kMul8);
 908  E :    EXPECT_FALSE(are_arithmetic_flags_live());
 909  E :    EXPECT_TRUE(is_live(assm::eax));
 910  E :    EXPECT_FALSE(is_live(assm::ebx));
 911  E :    EXPECT_TRUE(is_live(assm::ecx));
 912  E :    EXPECT_FALSE(is_live(assm::edx));
 913  E :    EXPECT_FALSE(is_live(assm::ah));
 914  E :    EXPECT_TRUE(is_def(assm::eax));
 915  E :    EXPECT_TRUE(is_def(assm::ah));
 916  E :    EXPECT_FALSE(is_def(assm::ecx));
 917  E :    EXPECT_FALSE(is_def(assm::cl));
 918  E :    EXPECT_TRUE(is_use(assm::eax));
 919  E :    EXPECT_FALSE(is_use(assm::ah));
 920  E :    EXPECT_TRUE(is_use(assm::al));
 921  E :    EXPECT_TRUE(is_use(assm::ecx));
 922  E :    EXPECT_FALSE(is_use(assm::ch));
 923  E :    EXPECT_TRUE(is_use(assm::cl));
 924    :  
 925    :    // _asm mul ah
 926    :    static const uint8 kMul16High[] = { 0xF6, 0xE4 };
 927  E :    AnalyzeSingleInstructionFromBuffer(kMul16High);
 928  E :    EXPECT_FALSE(are_arithmetic_flags_live());
 929  E :    EXPECT_TRUE(is_live(assm::eax));
 930  E :    EXPECT_FALSE(is_live(assm::ebx));
 931  E :    EXPECT_FALSE(is_live(assm::ecx));
 932  E :    EXPECT_FALSE(is_live(assm::edx));
 933  E :    EXPECT_TRUE(is_live(assm::ah));
 934  E :    EXPECT_TRUE(is_def(assm::eax));
 935  E :    EXPECT_TRUE(is_def(assm::ah));
 936  E :    EXPECT_TRUE(is_def(assm::al));
 937  E :    EXPECT_FALSE(is_def(assm::dl));
 938  E :    EXPECT_TRUE(is_use(assm::ah));
 939  E :    EXPECT_TRUE(is_use(assm::al));
 940  E :    EXPECT_FALSE(is_use(assm::dl));
 941    :  
 942    :    // _asm imul ecx
 943    :    static const uint8 kIMul32[] = { 0xF7, 0xE9 };
 944  E :    AnalyzeSingleInstructionFromBuffer(kIMul32);
 945  E :    EXPECT_FALSE(are_arithmetic_flags_live());
 946  E :    EXPECT_TRUE(is_live(assm::eax));
 947  E :    EXPECT_FALSE(is_live(assm::ebx));
 948  E :    EXPECT_TRUE(is_live(assm::ecx));
 949  E :    EXPECT_FALSE(is_live(assm::edx));
 950  E :    EXPECT_TRUE(is_def(assm::al));
 951  E :    EXPECT_TRUE(is_def(assm::dl));
 952  E :    EXPECT_TRUE(is_use(assm::ecx));
 953    :  
 954    :    // _asm imul cx
 955    :    static const uint8 kIMul16[] = { 0xF7, 0xE9 };
 956  E :    AnalyzeSingleInstructionFromBuffer(kIMul16);
 957  E :    EXPECT_FALSE(are_arithmetic_flags_live());
 958  E :    EXPECT_TRUE(is_live(assm::eax));
 959  E :    EXPECT_FALSE(is_live(assm::ebx));
 960  E :    EXPECT_TRUE(is_live(assm::ecx));
 961  E :    EXPECT_FALSE(is_live(assm::edx));
 962  E :    EXPECT_TRUE(is_def(assm::al));
 963  E :    EXPECT_TRUE(is_def(assm::dl));
 964  E :    EXPECT_TRUE(is_use(assm::ecx));
 965    :  
 966    :    // _asm imul cl
 967    :    static const uint8 kIMul8[] = { 0xF6, 0xE9 };
 968  E :    AnalyzeSingleInstructionFromBuffer(kIMul8);
 969  E :    EXPECT_FALSE(are_arithmetic_flags_live());
 970  E :    EXPECT_TRUE(is_live(assm::eax));
 971  E :    EXPECT_FALSE(is_live(assm::ebx));
 972  E :    EXPECT_TRUE(is_live(assm::ecx));
 973  E :    EXPECT_FALSE(is_live(assm::edx));
 974  E :    EXPECT_FALSE(is_live(assm::ch));
 975  E :    EXPECT_TRUE(is_def(assm::al));
 976  E :    EXPECT_FALSE(is_def(assm::dl));
 977  E :    EXPECT_TRUE(is_use(assm::ecx));
 978    :  
 979    :    // _asm imul ah
 980    :    static const uint8 kIMul16High[] = { 0xF6, 0xEC };
 981  E :    AnalyzeSingleInstructionFromBuffer(kIMul16High);
 982  E :    EXPECT_FALSE(are_arithmetic_flags_live());
 983  E :    EXPECT_TRUE(is_live(assm::eax));
 984  E :    EXPECT_FALSE(is_live(assm::ebx));
 985  E :    EXPECT_FALSE(is_live(assm::ecx));
 986  E :    EXPECT_FALSE(is_live(assm::edx));
 987  E :    EXPECT_TRUE(is_live(assm::ah));
 988  E :    EXPECT_TRUE(is_def(assm::al));
 989  E :    EXPECT_TRUE(is_def(assm::ah));
 990  E :    EXPECT_TRUE(is_use(assm::al));
 991  E :    EXPECT_TRUE(is_use(assm::ah));
 992  E :    EXPECT_FALSE(is_def(assm::dl));
 993    :  
 994    :    // _asm imul eax, 3
 995    :    static const uint8 kIMul32ByCst[] = { 0x6B, 0xC0, 0x03 };
 996  E :    AnalyzeSingleInstructionFromBuffer(kIMul32ByCst);
 997  E :    EXPECT_FALSE(are_arithmetic_flags_live());
 998  E :    EXPECT_TRUE(is_live(assm::eax));
 999  E :    EXPECT_FALSE(is_live(assm::ebx));
1000  E :    EXPECT_FALSE(is_live(assm::ecx));
1001  E :    EXPECT_FALSE(is_live(assm::edx));
1002  E :    EXPECT_TRUE(is_def(assm::eax));
1003  E :    EXPECT_TRUE(is_use(assm::eax));
1004  E :    EXPECT_FALSE(is_def(assm::dl));
1005    :  
1006    :    // _asm imul ecx, 3
1007    :    static const uint8 kIMul32EcxByCst[] = { 0x6B, 0xC9, 0x03 };
1008  E :    AnalyzeSingleInstructionFromBuffer(kIMul32EcxByCst);
1009  E :    EXPECT_FALSE(are_arithmetic_flags_live());
1010  E :    EXPECT_FALSE(are_arithmetic_flags_live());
1011  E :    EXPECT_FALSE(is_live(assm::eax));
1012  E :    EXPECT_FALSE(is_live(assm::ebx));
1013  E :    EXPECT_TRUE(is_live(assm::ecx));
1014  E :    EXPECT_FALSE(is_live(assm::edx));
1015  E :    EXPECT_FALSE(is_def(assm::eax));
1016  E :    EXPECT_TRUE(is_def(assm::ecx));
1017  E :    EXPECT_FALSE(is_def(assm::dl));
1018  E :    EXPECT_FALSE(is_use(assm::eax));
1019  E :    EXPECT_TRUE(is_use(assm::ecx));
1020  E :  }
1021    :  
1022  E :  TEST_F(LivenessAnalysisTest, ConversionInstructions) {
1023    :    static const uint8 kCdq[] = { 0x99 };
1024  E :    AnalyzeSingleInstructionFromBuffer(kCdq);
1025  E :    EXPECT_TRUE(is_live(assm::eax));
1026  E :    EXPECT_FALSE(is_live(assm::edx));
1027  E :    EXPECT_FALSE(are_arithmetic_flags_live());
1028  E :    EXPECT_TRUE(is_def(assm::eax));
1029  E :    EXPECT_TRUE(is_def(assm::edx));
1030  E :    EXPECT_TRUE(is_use(assm::eax));
1031  E :    EXPECT_FALSE(is_use(assm::edx));
1032    :  
1033    :    static const uint8 kCwd[] = { 0x66, 0x99 };
1034  E :    AnalyzeSingleInstructionFromBuffer(kCwd);
1035  E :    EXPECT_TRUE(is_live(assm::eax));
1036  E :    EXPECT_FALSE(is_live(assm::edx));
1037  E :    EXPECT_FALSE(are_arithmetic_flags_live());
1038  E :    EXPECT_TRUE(is_def(assm::eax));
1039  E :    EXPECT_FALSE(is_def(assm::edx));
1040  E :    EXPECT_TRUE(is_use(assm::eax));
1041  E :    EXPECT_FALSE(is_use(assm::edx));
1042  E :  }
1043    :  
1044  E :  TEST_F(LivenessAnalysisTest, EpilogueInstructions) {
1045    :    static const uint8 kLeave[] = { 0xC9 };
1046  E :    AnalyzeSingleInstructionFromBuffer(kLeave);
1047  E :    EXPECT_TRUE(is_live(assm::ebp));
1048  E :    EXPECT_TRUE(is_live(assm::esp));
1049  E :    EXPECT_FALSE(are_arithmetic_flags_live());
1050  E :    EXPECT_TRUE(is_def(assm::esp));
1051  E :    EXPECT_TRUE(is_def(assm::ebp));
1052  E :    EXPECT_TRUE(is_use(assm::esp));
1053  E :    EXPECT_TRUE(is_use(assm::esp));
1054  E :  }
1055    :  
1056  E :  TEST_F(LivenessAnalysisTest, StackInstructions) {
1057    :    // Validate instructions that push/pop on the stack.
1058    :    // _asm push eax
1059    :    static const uint8 kPushd[] = { 0x50 };
1060  E :    AnalyzeSingleInstructionFromBuffer(kPushd);
1061  E :    EXPECT_TRUE(is_live(assm::esp));
1062  E :    EXPECT_TRUE(is_live(assm::eax));
1063  E :    EXPECT_TRUE(is_def(assm::esp));
1064  E :    EXPECT_TRUE(is_use(assm::esp));
1065    :  
1066    :    // _asm pop eax
1067    :    static const uint8 kPopd[] = { 0x58 };
1068  E :    AnalyzeSingleInstructionFromBuffer(kPopd);
1069  E :    EXPECT_TRUE(is_live(assm::esp));
1070  E :    EXPECT_FALSE(is_live(assm::eax));
1071  E :    EXPECT_TRUE(is_def(assm::esp));
1072  E :    EXPECT_TRUE(is_use(assm::esp));
1073    :  
1074    :    // _asm push ax
1075    :    static const uint8 kPush[] = { 0x66, 0x50 };
1076  E :    AnalyzeSingleInstructionFromBuffer(kPush);
1077  E :    EXPECT_TRUE(is_live(assm::esp));
1078  E :    EXPECT_TRUE(is_live(assm::eax));
1079  E :    EXPECT_TRUE(is_def(assm::esp));
1080  E :    EXPECT_TRUE(is_use(assm::esp));
1081    :  
1082    :    // _asm pop ax
1083    :    static const uint8 kPop[] = { 0x66, 0x58 };
1084  E :    AnalyzeSingleInstructionFromBuffer(kPop);
1085  E :    EXPECT_TRUE(is_live(assm::esp));
1086  E :    EXPECT_FALSE(is_live(assm::eax));
1087  E :    EXPECT_TRUE(is_def(assm::esp));
1088  E :    EXPECT_TRUE(is_use(assm::esp));
1089    :  
1090    :    static const uint8 kPopSMem[] = { 0x66, 0x8F, 0x00 };
1091  E :    AnalyzeSingleInstructionFromBuffer(kPopSMem);
1092  E :    EXPECT_TRUE(is_live(assm::esp));
1093  E :    EXPECT_TRUE(is_live(assm::eax));
1094  E :    EXPECT_TRUE(is_def(assm::esp));
1095  E :    EXPECT_TRUE(is_use(assm::esp));
1096  E :  }
1097    :  
1098  E :  TEST_F(LivenessAnalysisTest, SetFlagInstructions) {
1099    :    // Validate instructions that consume flags. Ensure flags are used.
1100    :  
1101    :    // _asm seta al
1102    :    static const uint8 kSetA[] = { 0x0F, 0x97, 0xC0 };
1103  E :    AnalyzeSingleInstructionFromBuffer(kSetA);
1104  E :    EXPECT_TRUE(are_arithmetic_flags_live());
1105  E :    EXPECT_TRUE(is_def(assm::al));
1106  E :    EXPECT_FALSE(is_use(assm::al));
1107    :  
1108    :    // _asm setae al
1109    :    static const uint8 kSetAE[] = { 0x0F, 0x93, 0xC0 };
1110  E :    AnalyzeSingleInstructionFromBuffer(kSetAE);
1111  E :    EXPECT_TRUE(are_arithmetic_flags_live());
1112    :  
1113    :    // _asm setb al
1114    :    static const uint8 kSetB[] = { 0x0F, 0x92, 0xC0 };
1115  E :    AnalyzeSingleInstructionFromBuffer(kSetB);
1116  E :    EXPECT_TRUE(are_arithmetic_flags_live());
1117    :  
1118    :    // _asm setbe al
1119    :    static const uint8 kSetBE[] = { 0x0F, 0x96, 0xC0 };
1120  E :    AnalyzeSingleInstructionFromBuffer(kSetBE);
1121  E :    EXPECT_TRUE(are_arithmetic_flags_live());
1122    :  
1123    :    // _asm setg al
1124    :    static const uint8 kSetG[] = { 0x0F, 0x9F, 0xC0 };
1125  E :    AnalyzeSingleInstructionFromBuffer(kSetG);
1126  E :    EXPECT_TRUE(are_arithmetic_flags_live());
1127    :  
1128    :    // _asm setge al
1129    :    static const uint8 kSetGE[] = { 0x0F, 0x9D, 0xC0 };
1130  E :    AnalyzeSingleInstructionFromBuffer(kSetGE);
1131  E :    EXPECT_TRUE(are_arithmetic_flags_live());
1132    :  
1133    :    // _asm setl al
1134    :    static const uint8 kSetL[] = { 0x0F, 0x9C, 0xC0 };
1135  E :    AnalyzeSingleInstructionFromBuffer(kSetL);
1136  E :    EXPECT_TRUE(are_arithmetic_flags_live());
1137    :  
1138    :    // _asm setle al
1139    :    static const uint8 kSetLE[] = { 0x0F, 0x9E, 0xC0 };
1140  E :    AnalyzeSingleInstructionFromBuffer(kSetLE);
1141  E :    EXPECT_TRUE(are_arithmetic_flags_live());
1142    :  
1143    :    // _asm setno al
1144    :    static const uint8 kSetNO[] = { 0x0F, 0x91, 0xC0 };
1145  E :    AnalyzeSingleInstructionFromBuffer(kSetNO);
1146  E :    EXPECT_TRUE(are_arithmetic_flags_live());
1147    :  
1148    :    // _asm setnp al
1149    :    static const uint8 kSetNP[] = { 0x0F, 0x9B, 0xC0 };
1150  E :    AnalyzeSingleInstructionFromBuffer(kSetNP);
1151  E :    EXPECT_TRUE(are_arithmetic_flags_live());
1152    :  
1153    :    // _asm setns al
1154    :    static const uint8 kSetNS[] = { 0x0F, 0x99, 0xC0 };
1155  E :    AnalyzeSingleInstructionFromBuffer(kSetNS);
1156  E :    EXPECT_TRUE(are_arithmetic_flags_live());
1157    :  
1158    :    // _asm setnz al
1159    :    static const uint8 kSetNZ[] = { 0x0F, 0x95, 0xC0 };
1160  E :    AnalyzeSingleInstructionFromBuffer(kSetNZ);
1161  E :    EXPECT_TRUE(are_arithmetic_flags_live());
1162    :  
1163    :    // _asm seto al
1164    :    static const uint8 kSetO[] = { 0x0F, 0x90, 0xC0 };
1165  E :    AnalyzeSingleInstructionFromBuffer(kSetO);
1166  E :    EXPECT_TRUE(are_arithmetic_flags_live());
1167    :  
1168    :    // _asm setp al
1169    :    static const uint8 kSetP[] = { 0x0F, 0x9A, 0xC0 };
1170  E :    AnalyzeSingleInstructionFromBuffer(kSetP);
1171  E :    EXPECT_TRUE(are_arithmetic_flags_live());
1172    :  
1173    :    // _asm sets al
1174    :    static const uint8 kSetS[] = { 0x0F, 0x98, 0xC0 };
1175  E :    AnalyzeSingleInstructionFromBuffer(kSetS);
1176  E :    EXPECT_TRUE(are_arithmetic_flags_live());
1177    :  
1178    :    // _asm setz al
1179    :    static const uint8 kSetZ[] = { 0x0F, 0x94, 0xC0 };
1180  E :    AnalyzeSingleInstructionFromBuffer(kSetZ);
1181  E :    EXPECT_TRUE(are_arithmetic_flags_live());
1182  E :  }
1183    :  
1184  E :  TEST_F(LivenessAnalysisTest, PushPopFlagsInstructions) {
1185    :    // Validate instructions that push/pop flags. Ensure flags are used, and stack
1186    :    // pointer is modified.
1187    :  
1188    :    // _asm pushfd
1189    :    static const uint8 kPushfd[] = { 0x9C };
1190  E :    AnalyzeSingleInstructionFromBuffer(kPushfd);
1191  E :    EXPECT_TRUE(are_arithmetic_flags_live());
1192  E :    EXPECT_TRUE(is_live(assm::esp));
1193  E :    EXPECT_TRUE(is_def(assm::esp));
1194  E :    EXPECT_TRUE(is_use(assm::esp));
1195    :  
1196    :    // _asm popfd
1197    :    static const uint8 kPopfd[] = { 0x9D };
1198  E :    AnalyzeSingleInstructionFromBuffer(kPopfd);
1199  E :    EXPECT_FALSE(are_arithmetic_flags_live());
1200  E :    EXPECT_TRUE(is_live(assm::esp));
1201  E :    EXPECT_TRUE(is_def(assm::esp));
1202  E :    EXPECT_TRUE(is_use(assm::esp));
1203    :  
1204    :    // _asm pushf
1205    :    static const uint8 kPushf[] = { 0x66, 0x9C };
1206  E :    AnalyzeSingleInstructionFromBuffer(kPushf);
1207  E :    EXPECT_TRUE(are_arithmetic_flags_live());
1208  E :    EXPECT_TRUE(is_live(assm::esp));
1209  E :    EXPECT_TRUE(is_def(assm::esp));
1210  E :    EXPECT_TRUE(is_use(assm::esp));
1211    :  
1212    :    // _asm popf
1213    :    static const uint8 kPopf[] = { 0x66, 0x9D };
1214  E :    AnalyzeSingleInstructionFromBuffer(kPopf);
1215  E :    EXPECT_FALSE(are_arithmetic_flags_live());
1216  E :    EXPECT_TRUE(is_live(assm::esp));
1217  E :    EXPECT_TRUE(is_def(assm::esp));
1218  E :    EXPECT_TRUE(is_use(assm::esp));
1219  E :  }
1220    :  
1221  E :  TEST_F(LivenessAnalysisTest, LoadStoreFlagsInstructions) {
1222    :    // Validate instructions that load/store flags. Ensure flags are defined or
1223    :    // used, and stack pointer is not modified.
1224    :  
1225    :    // _asm sahf
1226    :    static const uint8 kSahf[] = { 0x9E };
1227  E :    AnalyzeSingleInstructionFromBuffer(kSahf);
1228  E :    EXPECT_FALSE(are_arithmetic_flags_live());
1229  E :    EXPECT_FALSE(is_live(assm::esp));
1230  E :    EXPECT_TRUE(is_live(assm::eax));
1231  E :    EXPECT_FALSE(is_def(assm::ah));
1232  E :    EXPECT_TRUE(is_use(assm::ah));
1233    :  
1234    :    // _asm lahf
1235    :    static const uint8 kLahf[] = { 0x9F };
1236  E :    AnalyzeSingleInstructionFromBuffer(kLahf);
1237  E :    EXPECT_TRUE(are_arithmetic_flags_live());
1238  E :    EXPECT_FALSE(is_live(assm::esp));
1239  E :    EXPECT_FALSE(is_live(assm::eax));
1240  E :    EXPECT_TRUE(is_def(assm::ah));
1241  E :    EXPECT_FALSE(is_use(assm::ah));
1242  E :  }
1243    :  
1244  E :  TEST_F(LivenessAnalysisTest, ExtendMovInstructions) {
1245    :    // _asm movsx eax, cl
1246    :    static const uint8 kMovsx1[] = { 0x0F, 0xBE, 0xC1 };
1247  E :    AnalyzeSingleInstructionFromBuffer(kMovsx1);
1248  E :    EXPECT_FALSE(are_arithmetic_flags_live());
1249  E :    EXPECT_FALSE(is_live(assm::eax));
1250  E :    EXPECT_TRUE(is_live(assm::ecx));
1251  E :    EXPECT_TRUE(is_def(assm::ah));
1252  E :    EXPECT_FALSE(is_use(assm::ch));
1253    :  
1254    :    // _asm movsx eax, BYTE PTR [ecx]
1255    :    static const uint8 kMovsx2[] = { 0x0F, 0xBE, 0x01 };
1256  E :    AnalyzeSingleInstructionFromBuffer(kMovsx2);
1257  E :    EXPECT_FALSE(are_arithmetic_flags_live());
1258  E :    EXPECT_FALSE(is_live(assm::eax));
1259  E :    EXPECT_TRUE(is_live(assm::ecx));
1260    :  
1261    :    // _asm movzx eax, cl
1262    :    static const uint8 kMovzx1[] = { 0x0F, 0xB6, 0xC1 };
1263  E :    AnalyzeSingleInstructionFromBuffer(kMovzx1);
1264  E :    EXPECT_FALSE(are_arithmetic_flags_live());
1265  E :    EXPECT_FALSE(is_live(assm::eax));
1266  E :    EXPECT_TRUE(is_live(assm::ecx));
1267    :  
1268    :    // _asm movzx eax, BYTE PTR [ecx]
1269    :    static const uint8 kMovzx2[] = { 0x0F, 0xB6, 0x01 };
1270  E :    AnalyzeSingleInstructionFromBuffer(kMovzx2);
1271  E :    EXPECT_FALSE(are_arithmetic_flags_live());
1272  E :    EXPECT_FALSE(is_live(assm::eax));
1273  E :    EXPECT_TRUE(is_live(assm::ecx));
1274  E :  }
1275    :  
1276  E :  TEST_F(LivenessAnalysisTest, StringInstructions) {
1277    :    // movs dword ptr es:[edi], dword ptr [esi]
1278    :    static const uint8 kMovsl[] = { 0xA5 };
1279  E :    AnalyzeSingleInstructionFromBuffer(kMovsl);
1280  E :    EXPECT_TRUE(is_live(assm::esi));
1281  E :    EXPECT_TRUE(is_live(assm::edi));
1282  E :    EXPECT_FALSE(is_live(assm::ecx));
1283  E :    EXPECT_FALSE(are_arithmetic_flags_live());
1284  E :    EXPECT_TRUE(is_def(assm::esi));
1285  E :    EXPECT_TRUE(is_def(assm::edi));
1286  E :    EXPECT_TRUE(is_use(assm::esi));
1287  E :    EXPECT_TRUE(is_use(assm::edi));
1288    :  
1289    :    // movs byte ptr es:[edi], byte ptr [esi]
1290    :    static const uint8 kMovsb[] = { 0xA4 };
1291  E :    AnalyzeSingleInstructionFromBuffer(kMovsb);
1292  E :    EXPECT_TRUE(is_live(assm::esi));
1293  E :    EXPECT_TRUE(is_live(assm::edi));
1294  E :    EXPECT_FALSE(is_live(assm::ecx));
1295  E :    EXPECT_FALSE(are_arithmetic_flags_live());
1296    :  
1297    :    // stos dword ptr es:[edi]
1298    :    static const uint8 kStosl[] = { 0xAB };
1299  E :    AnalyzeSingleInstructionFromBuffer(kStosl);
1300  E :    EXPECT_FALSE(is_live(assm::esi));
1301  E :    EXPECT_TRUE(is_live(assm::edi));
1302  E :    EXPECT_FALSE(is_live(assm::ecx));
1303  E :    EXPECT_FALSE(are_arithmetic_flags_live());
1304  E :    EXPECT_FALSE(is_def(assm::esi));
1305  E :    EXPECT_TRUE(is_def(assm::edi));
1306  E :    EXPECT_FALSE(is_use(assm::esi));
1307  E :    EXPECT_TRUE(is_use(assm::edi));
1308    :  
1309    :    // stos byte ptr es:[edi]
1310    :    static const uint8 Stosb[] = { 0xAA };
1311  E :    AnalyzeSingleInstructionFromBuffer(Stosb);
1312  E :    EXPECT_FALSE(is_live(assm::esi));
1313  E :    EXPECT_TRUE(is_live(assm::edi));
1314  E :    EXPECT_FALSE(is_live(assm::ecx));
1315  E :    EXPECT_FALSE(are_arithmetic_flags_live());
1316  E :  }
1317    :  
1318  E :  TEST_F(LivenessAnalysisTest, PrefixedStringInstructions) {
1319    :    // repne movs dword ptr es:[edi], dword ptr [esi]
1320    :    static const uint8 kMovsl[] = { 0xF2, 0xA5 };
1321  E :    AnalyzeSingleInstructionFromBuffer(kMovsl);
1322  E :    EXPECT_TRUE(is_live(assm::esi));
1323  E :    EXPECT_TRUE(is_live(assm::edi));
1324  E :    EXPECT_TRUE(is_live(assm::ecx));
1325  E :    EXPECT_FALSE(are_arithmetic_flags_live());
1326    :  
1327    :    // repne movs byte ptr es:[edi], byte ptr [esi]
1328    :    static const uint8 kMovsb[] = { 0xF2, 0xA4 };
1329  E :    AnalyzeSingleInstructionFromBuffer(kMovsb);
1330  E :    EXPECT_TRUE(is_live(assm::esi));
1331  E :    EXPECT_TRUE(is_live(assm::edi));
1332  E :    EXPECT_TRUE(is_live(assm::ecx));
1333  E :    EXPECT_FALSE(are_arithmetic_flags_live());
1334    :  
1335    :    // repne stos dword ptr es:[edi]
1336    :    static const uint8 kStosl[] = { 0xF2, 0xAB };
1337  E :    AnalyzeSingleInstructionFromBuffer(kStosl);
1338  E :    EXPECT_FALSE(is_live(assm::esi));
1339  E :    EXPECT_TRUE(is_live(assm::edi));
1340  E :    EXPECT_TRUE(is_live(assm::ecx));
1341  E :    EXPECT_FALSE(are_arithmetic_flags_live());
1342    :  
1343    :    // repne stos byte ptr es:[edi]
1344    :    static const uint8 Stosb[] = { 0xF2, 0xAA };
1345  E :    AnalyzeSingleInstructionFromBuffer(Stosb);
1346  E :    EXPECT_FALSE(is_live(assm::esi));
1347  E :    EXPECT_TRUE(is_live(assm::edi));
1348  E :    EXPECT_TRUE(is_live(assm::ecx));
1349  E :    EXPECT_FALSE(are_arithmetic_flags_live());
1350  E :  }
1351    :  
1352  E :  TEST_F(LivenessAnalysisTest, FloatingPointInstructions) {
1353    :    // _asm fld1
1354    :    static const uint8 kFld1[] = { 0xD9, 0xE8 };
1355    :    // _asm fldz
1356    :    static const uint8 kFldz[] = { 0xD9, 0xEE };
1357    :    // _asm fadd
1358    :    static const uint8 kFadd[] = { 0xDE, 0xC1 };
1359    :    // _asm faddp st(3), st(0)
1360    :    static const uint8 kFaddp[] = { 0xDE, 0xC3 };
1361    :    // _asm fsub
1362    :    static const uint8 kFsub[] = { 0xDE, 0xE9 };
1363    :    // _asm fsubp st(3), st(0)
1364    :    static const uint8 kFsubp[] = { 0xDE, 0xEB };
1365    :    // _asm fmul
1366    :    static const uint8 kFmul[] = { 0xDE, 0xC9 };
1367    :    // _asm fmulp st(3), st(0)
1368    :    static const uint8 kFmulp[] = { 0xDE, 0xCB };
1369    :  
1370    :    // Floating point instructions don't touch any register nor general registers.
1371  E :    AddInstructionFromBuffer(kFld1);
1372  E :    AddInstructionFromBuffer(kFldz);
1373  E :    AddInstructionFromBuffer(kFadd);
1374  E :    AddInstructionFromBuffer(kFaddp);
1375  E :    AddInstructionFromBuffer(kFsub);
1376  E :    AddInstructionFromBuffer(kFsubp);
1377  E :    AddInstructionFromBuffer(kFmul);
1378  E :    AddInstructionFromBuffer(kFmulp);
1379  E :    DefineAllRegisters();
1380  E :    AnalyzeInstructions();
1381    :  
1382  E :    EXPECT_FALSE(is_live(assm::eax));
1383  E :    EXPECT_FALSE(is_live(assm::ebx));
1384  E :    EXPECT_FALSE(is_live(assm::ecx));
1385  E :    EXPECT_FALSE(is_live(assm::edx));
1386  E :    EXPECT_FALSE(is_live(assm::esi));
1387  E :    EXPECT_FALSE(is_live(assm::edi));
1388  E :    EXPECT_FALSE(are_arithmetic_flags_live());
1389  E :  }
1390    :  
1391  E :  TEST_F(LivenessAnalysisTest, FloatingPointMemoryInstructions) {
1392    :    // _asm fld DWORD PTR [eax + ecx]
1393    :    static const uint8 kFld[] = { 0xD9, 0x04, 0x08 };
1394  E :    AnalyzeSingleInstructionFromBuffer(kFld);
1395  E :    EXPECT_TRUE(is_live(assm::eax));
1396  E :    EXPECT_FALSE(is_live(assm::ebx));
1397  E :    EXPECT_TRUE(is_live(assm::ecx));
1398  E :    EXPECT_FALSE(are_arithmetic_flags_live());
1399    :  
1400    :    // _asm fst DWORD PTR [eax + ecx]
1401    :    static const uint8 kFst[] = { 0xD9, 0x14, 0x08 };
1402  E :    AnalyzeSingleInstructionFromBuffer(kFst);
1403  E :    EXPECT_TRUE(is_live(assm::eax));
1404  E :    EXPECT_FALSE(is_live(assm::ebx));
1405  E :    EXPECT_TRUE(is_live(assm::ecx));
1406  E :    EXPECT_FALSE(are_arithmetic_flags_live());
1407    :  
1408    :    // _asm fstp DWORD PTR [eax + ecx]
1409    :    static const uint8 kFstp[] = { 0xD9, 0x1C, 0x08 };
1410  E :    AnalyzeSingleInstructionFromBuffer(kFstp);
1411  E :    EXPECT_TRUE(is_live(assm::eax));
1412  E :    EXPECT_FALSE(is_live(assm::ebx));
1413  E :    EXPECT_TRUE(is_live(assm::ecx));
1414  E :    EXPECT_FALSE(are_arithmetic_flags_live());
1415    :  
1416    :    // _asm fadd DWORD PTR [eax]
1417    :    static const uint8 kFadd[] = { 0xD8, 0x00 };
1418  E :    AnalyzeSingleInstructionFromBuffer(kFadd);
1419  E :    EXPECT_TRUE(is_live(assm::eax));
1420  E :    EXPECT_FALSE(are_arithmetic_flags_live());
1421    :  
1422    :    // _asm fsub DWORD PTR [ecx]
1423    :    static const uint8 kFsub[] = { 0xD8, 0x21 };
1424  E :    AnalyzeSingleInstructionFromBuffer(kFsub);
1425  E :    EXPECT_TRUE(is_live(assm::ecx));
1426  E :    EXPECT_FALSE(are_arithmetic_flags_live());
1427    :  
1428    :    // _asm fmul DWORD PTR [esi]
1429    :    static const uint8 kFmul[] = { 0xD8, 0x0E };
1430  E :    AnalyzeSingleInstructionFromBuffer(kFmul);
1431  E :    EXPECT_TRUE(is_live(assm::esi));
1432  E :    EXPECT_FALSE(are_arithmetic_flags_live());
1433    :  
1434    :    // _asm fild DWORD PTR [eax]
1435    :    static const uint8 kFild[] = { 0xDB, 0x00 };
1436  E :    AnalyzeSingleInstructionFromBuffer(kFild);
1437  E :    EXPECT_TRUE(is_live(assm::eax));
1438  E :    EXPECT_FALSE(are_arithmetic_flags_live());
1439    :  
1440    :    // _asm fist DWORD PTR [eax]
1441    :    static const uint8 kFist[] = { 0xDB, 0x10 };
1442  E :    AnalyzeSingleInstructionFromBuffer(kFist);
1443  E :    EXPECT_TRUE(is_live(assm::eax));
1444  E :    EXPECT_FALSE(are_arithmetic_flags_live());
1445    :  
1446    :    // _asm fistp DWORD PTR [eax]
1447    :    static const uint8 kFistp[] = { 0xDB, 0x18 };
1448  E :    AnalyzeSingleInstructionFromBuffer(kFistp);
1449  E :    EXPECT_TRUE(is_live(assm::eax));
1450  E :    EXPECT_FALSE(are_arithmetic_flags_live());
1451  E :  }
1452    :  
1453  E :  TEST_F(LivenessAnalysisTest, FloatingPointCompareInstructions) {
1454    :    // _asm fcom
1455    :    static const uint8 kFcom[] = { 0xD8, 0xD1 };
1456  E :    AnalyzeSingleInstructionFromBuffer(kFcom);
1457  E :    EXPECT_FALSE(are_arithmetic_flags_live());
1458    :  
1459    :    // _asm fcomp
1460    :    static const uint8 kFcomp[] = { 0xD8, 0xD9 };
1461  E :    AnalyzeSingleInstructionFromBuffer(kFcomp);
1462  E :    EXPECT_FALSE(are_arithmetic_flags_live());
1463    :  
1464    :    // _asm fcompp
1465    :    static const uint8 kFcompp[] = { 0xDE, 0xD9 };
1466  E :    AnalyzeSingleInstructionFromBuffer(kFcompp);
1467  E :    EXPECT_FALSE(are_arithmetic_flags_live());
1468    :  
1469    :    // _asm fcomi
1470    :    static const uint8 kFcomi[] = { 0xDB, 0xF1 };
1471  E :    AnalyzeSingleInstructionFromBuffer(kFcomi);
1472  E :    EXPECT_FALSE(are_arithmetic_flags_live());
1473    :  
1474    :    // _asm fcomip
1475    :    static const uint8 fcomip[] = { 0xDF, 0xF1 };
1476  E :    AnalyzeSingleInstructionFromBuffer(fcomip);
1477  E :    EXPECT_FALSE(are_arithmetic_flags_live());
1478  E :  }
1479    :  
1480  E :  TEST_F(LivenessAnalysisTest, FloatingPointCompareMemoryInstructions) {
1481    :    // _asm fcom qword ptr [edx+ecx*8]
1482    :    static const uint8 kFcom[] = { 0xDC, 0x14, 0xCA };
1483  E :    AnalyzeSingleInstructionFromBuffer(kFcom);
1484  E :    EXPECT_FALSE(is_live(assm::eax));
1485  E :    EXPECT_FALSE(is_live(assm::ebx));
1486  E :    EXPECT_TRUE(is_live(assm::ecx));
1487  E :    EXPECT_TRUE(is_live(assm::edx));
1488  E :    EXPECT_FALSE(are_arithmetic_flags_live());
1489    :  
1490    :    // _asm fcomp word ptr [edx+ecx*8]
1491    :    static const uint8 kFcomp[] = { 0xDC, 0x1C, 0xCA };
1492  E :    AnalyzeSingleInstructionFromBuffer(kFcomp);
1493  E :    EXPECT_FALSE(is_live(assm::eax));
1494  E :    EXPECT_FALSE(is_live(assm::ebx));
1495  E :    EXPECT_TRUE(is_live(assm::ecx));
1496  E :    EXPECT_TRUE(is_live(assm::edx));
1497  E :    EXPECT_FALSE(are_arithmetic_flags_live());
1498    :  
1499    :    // _asm ficom qword ptr [edx+ecx*8]
1500    :    static const uint8 kFicom[] = { 0xDE, 0x14, 0xCA };
1501  E :    AnalyzeSingleInstructionFromBuffer(kFicom);
1502  E :    EXPECT_FALSE(is_live(assm::eax));
1503  E :    EXPECT_FALSE(is_live(assm::ebx));
1504  E :    EXPECT_TRUE(is_live(assm::ecx));
1505  E :    EXPECT_TRUE(is_live(assm::edx));
1506  E :    EXPECT_FALSE(are_arithmetic_flags_live());
1507    :  
1508    :    // _asm ficomp word ptr [edx+ecx*8]
1509    :    static const uint8 kFicomp[] = { 0xDE, 0x1C, 0xCA };
1510  E :    AnalyzeSingleInstructionFromBuffer(kFicomp);
1511  E :    EXPECT_FALSE(is_live(assm::eax));
1512  E :    EXPECT_FALSE(is_live(assm::ebx));
1513  E :    EXPECT_TRUE(is_live(assm::ecx));
1514  E :    EXPECT_TRUE(is_live(assm::edx));
1515  E :    EXPECT_FALSE(are_arithmetic_flags_live());
1516    :  
1517    :    // _asm ficom dword ptr [eax]
1518    :    static const uint8 kFicom2[] = { 0xDA, 0x10 };
1519  E :    AnalyzeSingleInstructionFromBuffer(kFicom2);
1520  E :    EXPECT_TRUE(is_live(assm::eax));
1521  E :    EXPECT_FALSE(is_live(assm::edx));
1522  E :    EXPECT_FALSE(are_arithmetic_flags_live());
1523    :  
1524    :    // _asm ficomp dword ptr [eax]
1525    :    static const uint8 ficomp2[] = { 0xDA, 0x18 };
1526  E :    AnalyzeSingleInstructionFromBuffer(ficomp2);
1527  E :    EXPECT_TRUE(is_live(assm::eax));
1528  E :    EXPECT_FALSE(is_live(assm::edx));
1529  E :    EXPECT_FALSE(are_arithmetic_flags_live());
1530  E :  }
1531    :  
1532  E :  TEST_F(LivenessAnalysisTest, FloatingPointCompareWithFlagsInstructions) {
1533    :    // Some floating point operations modify eflags.
1534    :  
1535    :    // _asm fcomi
1536    :    static const uint8 kFcomi[] = { 0xDB, 0xF1 };
1537  E :    AddInstructionFromBuffer(kFcomi);
1538  E :    EXPECT_TRUE(CheckCarryFlagInstruction(false, false));
1539  E :    instructions_.clear();
1540    :  
1541    :    // _asm fcomip
1542    :    static const uint8 fcomip[] = { 0xDF, 0xF1 };
1543  E :    AddInstructionFromBuffer(fcomip);
1544  E :    EXPECT_TRUE(CheckCarryFlagInstruction(false, false));
1545  E :    instructions_.clear();
1546  E :  }
1547    :  
1548  E :  TEST_F(LivenessAnalysisTest, UnknownInstruction) {
1549    :    // Ensure unknown instructions are processed correctly.
1550    :    static const uint8 kRdtsc[] = { 0x0F, 0x31 };
1551  E :    AnalyzeSingleInstructionFromBuffer(kRdtsc);
1552  E :    EXPECT_TRUE(is_live(assm::eax));
1553  E :    EXPECT_TRUE(is_live(assm::ecx));
1554  E :    EXPECT_TRUE(is_live(assm::esi));
1555  E :    EXPECT_TRUE(is_live(assm::ebp));
1556  E :    EXPECT_TRUE(are_arithmetic_flags_live());
1557  E :  }
1558    :  
1559  E :  TEST_F(LivenessAnalysisTest, XorInitializationSpecialCase) {
1560    :    // Validate an initialization pattern used by x86 compiler.
1561    :    // Ensure the flags are assumed modified, and the register is unused.
1562    :  
1563    :    // _asm xor eax, eax
1564    :    static const uint8 kXor1[] = { 0x33, 0xC0 };
1565  E :    AnalyzeSingleInstructionFromBuffer(kXor1);
1566  E :    EXPECT_FALSE(is_live(assm::eax));
1567  E :    EXPECT_FALSE(are_arithmetic_flags_live());
1568  E :    EXPECT_TRUE(is_def(assm::eax));
1569  E :    EXPECT_FALSE(is_use(assm::eax));
1570    :  
1571    :    // _asm xor ebx, ebx
1572    :    static const uint8 kXor2[] = { 0x33, 0xDB };
1573  E :    AnalyzeSingleInstructionFromBuffer(kXor2);
1574  E :    EXPECT_FALSE(is_live(assm::eax));
1575  E :    EXPECT_FALSE(are_arithmetic_flags_live());
1576  E :    EXPECT_TRUE(is_def(assm::ebx));
1577  E :    EXPECT_FALSE(is_use(assm::ebx));
1578    :  
1579    :    // _asm xor ecx, ecx
1580    :    static const uint8 kXor3[] = { 0x33, 0xC9 };
1581  E :    AnalyzeSingleInstructionFromBuffer(kXor3);
1582  E :    EXPECT_FALSE(is_live(assm::eax));
1583  E :    EXPECT_FALSE(are_arithmetic_flags_live());
1584  E :    EXPECT_TRUE(is_def(assm::ecx));
1585  E :    EXPECT_FALSE(is_use(assm::ecx));
1586  E :  }
1587    :  
1588  E :  TEST_F(LivenessAnalysisTest, NopInstructionSpecialCase) {
1589    :    // Nop should be ignored by the analysis.
1590  E :    asm_.mov(assm::eax, assm::eax);
1591  E :    asm_.mov(assm::eax, Immediate(10));
1592  E :    AnalyzeInstructions();
1593  E :    EXPECT_FALSE(is_live(assm::eax));
1594  E :  }
1595    :  
1596  E :  TEST_F(LivenessAnalysisTest, GetStateAtEntryOfWithNull) {
1597    :    // It is valid to pass a NULL pointer to get a state.
1598  E :    liveness_.GetStateAtEntryOf(NULL, &state_);
1599  E :    EXPECT_TRUE(is_live(assm::eax));
1600  E :    EXPECT_TRUE(is_live(assm::esi));
1601  E :    EXPECT_TRUE(are_arithmetic_flags_live());
1602  E :  }
1603    :  
1604  E :  TEST_F(LivenessAnalysisTest, GetStateAtExitOfWithNull) {
1605    :    // It is valid to pass a NULL pointer to get a state.
1606  E :    liveness_.GetStateAtExitOf(NULL, &state_);
1607  E :    EXPECT_TRUE(is_live(assm::eax));
1608  E :    EXPECT_TRUE(is_live(assm::esi));
1609  E :    EXPECT_TRUE(are_arithmetic_flags_live());
1610  E :  }
1611    :  
1612  E :  TEST_F(LivenessAnalysisTest, LivenessAnalysisOverControlFlow) {
1613  E :    BasicBlockSubGraph subgraph;
1614    :  
1615    :    // Build and analyze this flow graph:
1616    :    //               [if1]
1617    :    //            /          \
1618    :    //           /            \
1619    :    //      [true1]          [false1]
1620    :    //      mov esi, 1       mov esi, 2
1621    :    //                       mov edi, 2
1622    :    //           \             /
1623    :    //            \           /
1624    :    //                [if2]     <-----------
1625    :    //            /          \               \
1626    :    //           /            \               \
1627    :    //      [true2]          [false2]          \
1628    :    //      mov eax, ebx     mov ebp, esi       |
1629    :    //                       mov esi, edi       |
1630    :    //                       mov edi, ebp       |
1631    :    //                       mov eax, [esi]     |
1632    :    //           \             /                |
1633    :    //            \           /                 |
1634    :    //                [end2]                   /
1635    :    //                mov ecx, eax            /
1636    :    //                    \                  /
1637    :    //                     -----------------/
1638    :  
1639    :    // Create the control flow graph.
1640  E :    BasicCodeBlock* if1 = subgraph.AddBasicCodeBlock("if1");
1641  E :    BasicCodeBlock* true1 = subgraph.AddBasicCodeBlock("true1");
1642  E :    BasicCodeBlock* false1 = subgraph.AddBasicCodeBlock("false1");
1643  E :    BasicCodeBlock* if2 = subgraph.AddBasicCodeBlock("if2");
1644  E :    BasicCodeBlock* true2 = subgraph.AddBasicCodeBlock("true2");
1645  E :    BasicCodeBlock* false2 = subgraph.AddBasicCodeBlock("false2");
1646  E :    BasicCodeBlock* end2 = subgraph.AddBasicCodeBlock("end2");
1647    :  
1648  E :    ASSERT_TRUE(if1 != NULL);
1649  E :    ASSERT_TRUE(true1 != NULL);
1650  E :    ASSERT_TRUE(false1 != NULL);
1651  E :    ASSERT_TRUE(if2 != NULL);
1652  E :    ASSERT_TRUE(true2 != NULL);
1653  E :    ASSERT_TRUE(false2 != NULL);
1654  E :    ASSERT_TRUE(end2 != NULL);
1655    :  
1656  E :    AddSuccessorBetween(Successor::kConditionEqual, if1, true1);
1657  E :    AddSuccessorBetween(Successor::kConditionNotEqual, if1, false1);
1658  E :    AddSuccessorBetween(Successor::kConditionTrue, true1, if2);
1659  E :    AddSuccessorBetween(Successor::kConditionTrue, false1, if2);
1660    :  
1661  E :    AddSuccessorBetween(Successor::kConditionOverflow, if2, true2);
1662  E :    AddSuccessorBetween(Successor::kConditionNotOverflow, if2, false2);
1663  E :    AddSuccessorBetween(Successor::kConditionLess, true2, end2);
1664  E :    AddSuccessorBetween(Successor::kConditionLess, false2, end2);
1665    :  
1666  E :    AddSuccessorBetween(Successor::kConditionTrue, end2, if2);
1667    :  
1668    :    // Insert instructions into basic blocks.
1669    :    BasicBlockAssembler asm_end2(end2->instructions().end(),
1670  E :                                 &end2->instructions());
1671  E :    asm_end2.mov(assm::ecx, assm::eax);
1672    :  
1673    :    BasicBlockAssembler asm_true2(true2->instructions().end(),
1674  E :                                  &true2->instructions());
1675  E :    asm_true2.mov(assm::eax, assm::ebx);
1676    :  
1677    :    BasicBlockAssembler asm_false2(false2->instructions().end(),
1678  E :                                   &false2->instructions());
1679  E :    asm_false2.mov(assm::ebp, assm::esi);
1680  E :    asm_false2.mov(assm::esi, assm::edi);
1681  E :    asm_false2.mov(assm::edi, assm::ebp);
1682  E :    asm_false2.mov(assm::eax, Operand(assm::esi));
1683    :  
1684    :    BasicBlockAssembler asm_true1(true1->instructions().end(),
1685  E :                                  &true1->instructions());
1686  E :    asm_true1.mov(assm::esi, Immediate(1));
1687    :  
1688    :    BasicBlockAssembler asm_false1(false1->instructions().end(),
1689  E :                                   &false1->instructions());
1690  E :    asm_false1.mov(assm::esi, Immediate(2));
1691  E :    asm_false1.mov(assm::edi, Immediate(2));
1692    :  
1693    :    // Perform global liveness analysis.
1694  E :    liveness_.Analyze(&subgraph);
1695    :  
1696    :    // Validate fix-point propagation.
1697  E :    liveness_.GetStateAtEntryOf(end2, &state_);
1698  E :    EXPECT_TRUE(is_live(assm::eax));
1699  E :    EXPECT_TRUE(is_live(assm::ebx));
1700  E :    EXPECT_FALSE(is_live(assm::ecx));
1701  E :    EXPECT_TRUE(is_live(assm::esi));
1702  E :    EXPECT_TRUE(is_live(assm::edi));
1703  E :    EXPECT_FALSE(is_live(assm::ebp));
1704    :  
1705  E :    liveness_.GetStateAtEntryOf(true2, &state_);
1706  E :    EXPECT_FALSE(is_live(assm::eax));
1707  E :    EXPECT_TRUE(is_live(assm::ebx));
1708  E :    EXPECT_FALSE(is_live(assm::ecx));
1709  E :    EXPECT_TRUE(is_live(assm::esi));
1710  E :    EXPECT_TRUE(is_live(assm::edi));
1711  E :    EXPECT_FALSE(is_live(assm::ebp));
1712    :  
1713  E :    liveness_.GetStateAtEntryOf(false2, &state_);
1714  E :    EXPECT_FALSE(is_live(assm::eax));
1715  E :    EXPECT_TRUE(is_live(assm::ebx));
1716  E :    EXPECT_FALSE(is_live(assm::ecx));
1717  E :    EXPECT_TRUE(is_live(assm::esi));
1718  E :    EXPECT_TRUE(is_live(assm::edi));
1719  E :    EXPECT_FALSE(is_live(assm::ebp));
1720    :  
1721  E :    liveness_.GetStateAtEntryOf(if2, &state_);
1722  E :    EXPECT_FALSE(is_live(assm::eax));
1723  E :    EXPECT_TRUE(is_live(assm::ebx));
1724  E :    EXPECT_FALSE(is_live(assm::ecx));
1725  E :    EXPECT_TRUE(is_live(assm::esi));
1726  E :    EXPECT_TRUE(is_live(assm::edi));
1727  E :    EXPECT_FALSE(is_live(assm::ebp));
1728    :  
1729  E :    liveness_.GetStateAtEntryOf(true1, &state_);
1730  E :    EXPECT_FALSE(is_live(assm::eax));
1731  E :    EXPECT_TRUE(is_live(assm::ebx));
1732  E :    EXPECT_FALSE(is_live(assm::ecx));
1733  E :    EXPECT_FALSE(is_live(assm::esi));
1734  E :    EXPECT_TRUE(is_live(assm::edi));
1735  E :    EXPECT_FALSE(is_live(assm::ebp));
1736    :  
1737  E :    liveness_.GetStateAtEntryOf(false1, &state_);
1738  E :    EXPECT_FALSE(is_live(assm::eax));
1739  E :    EXPECT_TRUE(is_live(assm::ebx));
1740  E :    EXPECT_FALSE(is_live(assm::ecx));
1741  E :    EXPECT_FALSE(is_live(assm::esi));
1742  E :    EXPECT_FALSE(is_live(assm::edi));
1743  E :    EXPECT_FALSE(is_live(assm::ebp));
1744    :  
1745  E :    liveness_.GetStateAtEntryOf(if1, &state_);
1746  E :    EXPECT_FALSE(is_live(assm::eax));
1747  E :    EXPECT_TRUE(is_live(assm::ebx));
1748  E :    EXPECT_FALSE(is_live(assm::ecx));
1749  E :    EXPECT_FALSE(is_live(assm::esi));
1750  E :    EXPECT_TRUE(is_live(assm::edi));
1751  E :    EXPECT_FALSE(is_live(assm::ebp));
1752  E :  }
1753    :  
1754  E :  TEST_F(LivenessAnalysisTest, AnalyzeWithData) {
1755  E :    BasicBlockSubGraph subgraph;
1756  E :    const uint8 raw_data[] = { 0, 1, 2, 3, 4 };
1757    :  
1758    :    BlockDescription* block = subgraph.AddBlockDescription(
1759  E :        "b1", "b1.obj", BlockGraph::CODE_BLOCK, 7, 2, 42);
1760    :  
1761  E :    BasicCodeBlock* bb = subgraph.AddBasicCodeBlock("bb");
1762    :    BasicDataBlock* data =
1763  E :        subgraph.AddBasicDataBlock("data", sizeof(raw_data), &raw_data[0]);
1764    :  
1765  E :    block->basic_block_order.push_back(bb);
1766  E :    block->basic_block_order.push_back(data);
1767    :  
1768  E :    BasicBlockAssembler asm_bb(bb->instructions().end(), &bb->instructions());
1769  E :    asm_bb.mov(assm::eax, assm::ebx);
1770  E :    asm_bb.ret();
1771    :  
1772    :    // Analyze the flow graph.
1773  E :    liveness_.Analyze(&subgraph);
1774    :  
1775  E :    liveness_.GetStateAtEntryOf(bb, &state_);
1776  E :    EXPECT_FALSE(is_live(assm::eax));
1777  E :    EXPECT_TRUE(is_live(assm::ebx));
1778  E :    EXPECT_TRUE(is_live(assm::esi));
1779    :  
1780  E :    liveness_.GetStateAtEntryOf(data, &state_);
1781  E :    EXPECT_TRUE(is_live(assm::eax));
1782  E :    EXPECT_TRUE(is_live(assm::ebx));
1783  E :    EXPECT_TRUE(is_live(assm::esi));
1784  E :  }
1785    :  
1786    :  }  // namespace
1787    :  
1788    :  }  // namespace analysis
1789    :  }  // namespace block_graph

Coverage information generated Thu Jan 14 17:40:38 2016.