Skip to content
This repository has been archived by the owner on Apr 23, 2021. It is now read-only.

Commit

Permalink
Comments of the reviewers addressed.
Browse files Browse the repository at this point in the history
  • Loading branch information
dfki-mako committed Dec 10, 2019
1 parent 97e231b commit 699216f
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 41 deletions.
38 changes: 21 additions & 17 deletions include/mlir/Analysis/Liveness.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,18 @@
#ifndef MLIR_ANALYSIS_LIVENESS_H
#define MLIR_ANALYSIS_LIVENESS_H

#include <vector>
#include "mlir/Support/LLVM.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallPtrSet.h"
#include <vector>

namespace mlir {
class Block;
class LivenessBlockInfo;
class Operation;
class Region;
class Value;
class Operation;

class LivenessBlockInfo;

/// Represents an analysis for computing liveness information from a
/// given top-level operation. The analysis iterates over all associated
Expand All @@ -46,16 +46,16 @@ class LivenessBlockInfo;
/// included in the mentioned regions. It relies on a fixpoint iteration
/// to compute all live-in and live-out values of all included blocks.
/// Sample usage:
/// Liveness liveness(topLevelOp);
/// auto &allInValues = liveness.getLiveIn(block);
/// auto &allOutValues = liveness.getLiveOut(block);
/// auto allOperationsInWhichValueIsLive = liveness.resolveLiveness(value);
/// bool lastUse = liveness.isLastUse(value, operation);
/// Liveness liveness(topLevelOp);
/// auto &allInValues = liveness.getLiveIn(block);
/// auto &allOutValues = liveness.getLiveOut(block);
/// auto allOperationsInWhichValueIsLive = liveness.resolveLiveness(value);
/// bool lastUse = liveness.isLastUse(value, operation);
class Liveness {
public:
using OperationListT = std::vector<Operation *>;
using BlockMapT = llvm::DenseMap<Block *, LivenessBlockInfo>;
using ValueSetT = llvm::SmallDenseSet<Value *, 16>;
using BlockMapT = DenseMap<Block *, LivenessBlockInfo>;
using ValueSetT = SmallPtrSet<Value *, 16>;

public:
/// Creates a new Liveness analysis that computes liveness
Expand All @@ -67,7 +67,9 @@ class Liveness {

/// Gets liveness info (if any) for the given value.
/// This includes all operations in which the given value is live.
/// Note that the operations in this list are not ordered.
/// Note that the operations in this list are not ordered and the current
/// implementation is computationally expensive (as it iterates over all
/// blocks in which the given value is live).
OperationListT resolveLiveness(Value *value) const;

/// Gets liveness info (if any) for the block.
Expand All @@ -87,11 +89,11 @@ class Liveness {
void dump() const;

/// Dumps the liveness information to the given stream.
void print(llvm::raw_ostream &os) const;
void print(raw_ostream &os) const;

private:
/// Initializes the internal mappings.
void build(llvm::MutableArrayRef<Region> regions);
void build(MutableArrayRef<Region> regions);

private:
/// The operation this analysis was constructed from.
Expand Down Expand Up @@ -125,8 +127,10 @@ class LivenessBlockInfo {
/// Returns true if the given value is in the live-out set.
bool isLiveOut(Value *value) const;

/// Gets the start operation for the given value
/// (must be referenced in this block).
/// Gets the start operation for the given value. This is the first operation
/// the given value is considered to be live. This could either be the start
/// operation of the current block (in case the value is live-in) or the
/// operation that defines the given value (must be referenced in this block).
Operation *getStartOperation(Value *value) const;

/// Gets the end operation for the given value using the start operation
Expand Down
52 changes: 28 additions & 24 deletions lib/Analysis/Liveness.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "mlir/IR/Operation.h"
#include "mlir/IR/Region.h"
#include "mlir/IR/Value.h"
#include "llvm/ADT/SetOperations.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/Support/raw_ostream.h"

Expand All @@ -33,11 +34,11 @@ using namespace mlir;
struct BlockInfoBuilder {
using ValueSetT = Liveness::ValueSetT;

/// Fills the block builder with initial liveness information.
void build(Block *block) {
// Store block for further processing.
this->block = block;
/// Constructs an empty block builder.
BlockInfoBuilder() : block(nullptr) {}

/// Fills the block builder with initial liveness information.
BlockInfoBuilder(Block *block) : block(block) {
// Mark all block arguments (phis) as defined.
for (BlockArgument *argument : block->getArguments())
defValues.insert(argument);
Expand All @@ -46,7 +47,6 @@ struct BlockInfoBuilder {
// are inside this block or not (see outValues).
for (Operation &operation : *block)
for (Value *result : operation.getResults()) {
// Mark as defined
defValues.insert(result);

// Check whether this value will be in the outValues
Expand All @@ -63,8 +63,12 @@ struct BlockInfoBuilder {

// Check all operations for used operands.
for (Operation &operation : block->getOperations())
for (Value *operand : operation.getOperands())
useValues.insert(operand);
for (Value *operand : operation.getOperands()) {
// If the operand is already defined in the scope of this
// block, we can skip the value in the use set.
if (!defValues.count(operand))
useValues.insert(operand);
}
}

/// Updates live-in information of the current block.
Expand All @@ -74,11 +78,12 @@ struct BlockInfoBuilder {
/// false otherwise.
bool updateLiveIn() {
ValueSetT newIn = useValues;
newIn.insert(outValues.begin(), outValues.end());
// Subtract defValues
for (Value *defValue : defValues)
newIn.erase(defValue);
llvm::set_union(newIn, outValues);
llvm::set_subtract(newIn, defValues);

// It is sufficient to check the set sizes (instead of their contents)
// since the live-in set can only grow monotonically during all update
// operations.
if (newIn.size() == inValues.size())
return false;

Expand All @@ -93,7 +98,7 @@ struct BlockInfoBuilder {
void updateLiveOut(SourceT &source) {
for (Block *succ : block->getSuccessors()) {
BlockInfoBuilder &builder = source[succ];
outValues.insert(builder.inValues.begin(), builder.inValues.end());
llvm::set_union(outValues, builder.inValues);
}
}

Expand All @@ -114,18 +119,17 @@ struct BlockInfoBuilder {
};

/// Builds the internal liveness block mapping.
static void
buildBlockMapping(MutableArrayRef<Region> regions,
llvm::DenseMap<Block *, BlockInfoBuilder> &builders) {
static void buildBlockMapping(MutableArrayRef<Region> regions,
DenseMap<Block *, BlockInfoBuilder> &builders) {
llvm::SetVector<Block *> toProcess;

// Initialize all block structures
for (Region &region : regions)
for (Block &block : region) {
auto &blockBuilder = builders[&block];
blockBuilder.build(&block);
BlockInfoBuilder &builder =
builders.try_emplace(&block, &block).first->second;

if (blockBuilder.updateLiveIn())
if (builder.updateLiveIn())
toProcess.insert(block.pred_begin(), block.pred_end());
}

Expand Down Expand Up @@ -155,7 +159,7 @@ Liveness::Liveness(Operation *op) : operation(op) { build(op->getRegions()); }
void Liveness::build(MutableArrayRef<Region> regions) {

// Build internal block mapping.
llvm::DenseMap<Block *, BlockInfoBuilder> builders;
DenseMap<Block *, BlockInfoBuilder> builders;
buildBlockMapping(regions, builders);

// Store internal block data.
Expand All @@ -172,8 +176,8 @@ void Liveness::build(MutableArrayRef<Region> regions) {
/// Gets liveness info (if any) for the given value.
Liveness::OperationListT Liveness::resolveLiveness(Value *value) const {
OperationListT result;
llvm::SmallDenseSet<Block *, 32> visited;
llvm::SmallVector<Block *, 8> toProcess;
SmallPtrSet<Block *, 32> visited;
SmallVector<Block *, 8> toProcess;

// Start with the defining block
Block *currentBlock;
Expand Down Expand Up @@ -258,9 +262,9 @@ void Liveness::print(raw_ostream &os) const {
os << "// ---- Liveness -----\n";

// Builds unique block/value mappings for testing purposes.
llvm::DenseMap<Block *, size_t> blockIds;
llvm::DenseMap<Operation *, size_t> operationIds;
llvm::DenseMap<Value *, size_t> valueIds;
DenseMap<Block *, size_t> blockIds;
DenseMap<Operation *, size_t> operationIds;
DenseMap<Value *, size_t> valueIds;
for (Region &region : operation->getRegions())
for (Block &block : region) {
blockIds[&block] = blockIds.size();
Expand Down

0 comments on commit 699216f

Please sign in to comment.