/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "side_effects_analysis.h"

namespace art {

bool SideEffectsAnalysis::Run() {
  // Inlining might have created more blocks, so we need to increase the size
  // if needed.
  block_effects_.resize(graph_->GetBlocks().size());
  loop_effects_.resize(graph_->GetBlocks().size());

  // In DEBUG mode, ensure side effects are properly initialized to empty.
  if (kIsDebugBuild) {
    for (HBasicBlock* block : graph_->GetReversePostOrder()) {
      SideEffects effects = GetBlockEffects(block);
      DCHECK(effects.DoesNothing());
      if (block->IsLoopHeader()) {
        effects = GetLoopEffects(block);
        DCHECK(effects.DoesNothing());
      }
    }
  }

  // Do a post order visit to ensure we visit a loop header after its loop body.
  for (HBasicBlock* block : graph_->GetPostOrder()) {
    SideEffects effects = SideEffects::None();
    // Update `effects` with the side effects of all instructions in this block.
    for (HInstructionIterator inst_it(block->GetInstructions()); !inst_it.Done();
         inst_it.Advance()) {
      HInstruction* instruction = inst_it.Current();
      effects = effects.Union(instruction->GetSideEffects());
      // If all side effects are represented, scanning further will not add any
      // more information to side-effects of this block.
      if (effects.DoesAll()) {
        break;
      }
    }

    block_effects_[block->GetBlockId()] = effects;

    if (block->IsLoopHeader()) {
      // The side effects of the loop header are part of the loop.
      UpdateLoopEffects(block->GetLoopInformation(), effects);
      HBasicBlock* pre_header = block->GetLoopInformation()->GetPreHeader();
      if (pre_header->IsInLoop()) {
        // Update the side effects of the outer loop with the side effects of the inner loop.
        // Note that this works because we know all the blocks of the inner loop are visited
        // before the loop header of the outer loop.
        UpdateLoopEffects(pre_header->GetLoopInformation(), GetLoopEffects(block));
      }
    } else if (block->IsInLoop()) {
      // Update the side effects of the loop with the side effects of this block.
      UpdateLoopEffects(block->GetLoopInformation(), effects);
    }
  }
  has_run_ = true;
  return true;
}

SideEffects SideEffectsAnalysis::GetLoopEffects(HBasicBlock* block) const {
  DCHECK(block->IsLoopHeader());
  return loop_effects_[block->GetBlockId()];
}

SideEffects SideEffectsAnalysis::GetBlockEffects(HBasicBlock* block) const {
  return block_effects_[block->GetBlockId()];
}

void SideEffectsAnalysis::UpdateLoopEffects(HLoopInformation* info, SideEffects effects) {
  uint32_t id = info->GetHeader()->GetBlockId();
  loop_effects_[id] = loop_effects_[id].Union(effects);
}

}  // namespace art
