blob: 6a901d1c04737a5bcb2c368b972896e53fe8c425 [file] [log] [blame]
/*
* 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.
*/
#ifndef ART_COMPILER_OPTIMIZING_SSA_LIVENESS_ANALYSIS_H_
#define ART_COMPILER_OPTIMIZING_SSA_LIVENESS_ANALYSIS_H_
#include "nodes.h"
namespace art {
class BlockInfo : public ArenaObject {
public:
BlockInfo(ArenaAllocator* allocator, const HBasicBlock& block, size_t number_of_ssa_values)
: block_(block),
live_in_(allocator, number_of_ssa_values, false),
live_out_(allocator, number_of_ssa_values, false),
kill_(allocator, number_of_ssa_values, false) {
live_in_.ClearAllBits();
live_out_.ClearAllBits();
kill_.ClearAllBits();
}
private:
const HBasicBlock& block_;
ArenaBitVector live_in_;
ArenaBitVector live_out_;
ArenaBitVector kill_;
friend class SsaLivenessAnalysis;
DISALLOW_COPY_AND_ASSIGN(BlockInfo);
};
class SsaLivenessAnalysis : public ValueObject {
public:
explicit SsaLivenessAnalysis(const HGraph& graph)
: graph_(graph),
block_infos_(graph.GetArena(), graph.GetBlocks().Size()),
number_of_ssa_values_(0) {
block_infos_.SetSize(graph.GetBlocks().Size());
}
void Analyze();
BitVector* GetLiveInSet(const HBasicBlock& block) const {
return &block_infos_.Get(block.GetBlockId())->live_in_;
}
BitVector* GetLiveOutSet(const HBasicBlock& block) const {
return &block_infos_.Get(block.GetBlockId())->live_out_;
}
BitVector* GetKillSet(const HBasicBlock& block) const {
return &block_infos_.Get(block.GetBlockId())->kill_;
}
private:
// Give an SSA number to each instruction that defines a value used by another instruction.
void NumberInstructions();
// Compute live_in, live_out and kill sets.
void ComputeSets();
// Compute the initial live_in, live_out and kill sets, without analyzing
// backward branches.
void ComputeInitialSets();
// After computing the initial sets, this method does a fixed point
// calculation over the live_in and live_out set to take into account
// backwards branches.
void ComputeLiveInAndLiveOutSets();
// Update the live_in set of the block and returns whether it has changed.
bool UpdateLiveIn(const HBasicBlock& block);
// Update the live_out set of the block and returns whether it has changed.
bool UpdateLiveOut(const HBasicBlock& block);
const HGraph& graph_;
GrowableArray<BlockInfo*> block_infos_;
size_t number_of_ssa_values_;
DISALLOW_COPY_AND_ASSIGN(SsaLivenessAnalysis);
};
} // namespace art
#endif // ART_COMPILER_OPTIMIZING_SSA_LIVENESS_ANALYSIS_H_