/// the kernel to be executed. This region is not allowed to use values defined
/// outside it.
class LaunchOp : public Op<LaunchOp, OpTrait::AtLeastNOperands<6>::Impl,
- OpTrait::ZeroResult,
- OpTrait::NthRegionIsIsolatedAbove<0>::Impl> {
+ OpTrait::ZeroResult, OpTrait::IsIsolatedFromAbove> {
public:
using Op::Op;
/// Emit errors if `noteLoc` is provided; this location is used to point
/// to the operation containing the region, the actual error is reported at
/// the operation with an offending use.
- bool isIsolatedAbove(llvm::Optional<Location> noteLoc = llvm::None);
+ bool isIsolatedFromAbove(llvm::Optional<Location> noteLoc = llvm::None);
/// Walk the operations in this block in postorder, calling the callback for
/// each operation.
/// allowed to implicitly capture global values, and all external references
/// must use Function arguments or attributes.
class FuncOp : public Op<FuncOp, OpTrait::ZeroOperands, OpTrait::ZeroResult,
- OpTrait::NthRegionIsIsolatedAbove<0>::Impl> {
+ OpTrait::IsIsolatedFromAbove> {
public:
using Op::Op;
static StringRef getOperationName() { return "func"; }
}
};
-/// This verifiers that all operands used in N-th region of the given operation
-/// are defined within that region.
-template <unsigned RegionIdx> class NthRegionIsIsolatedAbove {
+/// This class provides the API for ops that are known to be isolated from
+/// above.
+template <typename ConcreteType>
+class IsIsolatedFromAbove
+ : public TraitBase<ConcreteType, IsIsolatedFromAbove> {
+public:
+ static AbstractOperation::OperationProperties getTraitProperties() {
+ return static_cast<AbstractOperation::OperationProperties>(
+ OperationProperty::IsolatedFromAbove);
+ }
+ static LogicalResult verifyTrait(Operation *op) {
+ for (auto ®ion : op->getRegions())
+ if (!region.isIsolatedFromAbove(op->getLoc()))
+ return failure();
+ return success();
+ }
+};
+
+/// This verifies that all operands used in N-th region of the given operation
+/// are defined within that region. This is a weaker variant to the
+/// 'IsIsolatedFromAbove' trait above as it applies only to one specific region.
+template <unsigned RegionIdx> class NthRegionIsIsolatedFromAbove {
public:
template <typename ConcreteType>
class Impl : public TraitBase<ConcreteType,
- NthRegionIsIsolatedAbove<RegionIdx>::Impl> {
+ NthRegionIsIsolatedFromAbove<RegionIdx>::Impl> {
public:
static LogicalResult verifyTrait(Operation *op) {
- return op->getRegion(RegionIdx).isIsolatedAbove(op->getLoc()) ? success()
- : failure();
+ return success(
+ op->getRegion(RegionIdx).isIsolatedFromAbove(op->getLoc()));
}
};
};
return getTerminatorStatus() == TerminatorStatus::NonTerminator;
}
+ /// Returns if the operation is known to be completely isolated from enclosing
+ /// regions, i.e. no internal regions reference values defined above this
+ /// operation.
+ bool isKnownIsolatedFromAbove() {
+ if (auto *absOp = getAbstractOperation())
+ return absOp->hasProperty(OperationProperty::IsolatedFromAbove);
+ return false;
+ }
+
/// Attempt to fold this operation with the specified constant operand values
/// - the elements in "operands" will correspond directly to the operands of
/// the operation, but may be null if non-constant. If folding is successful,
/// This bit is set for an operation if it is a terminator: that means
/// an operation at the end of a block.
Terminator = 0x4,
+
+ /// This bit is set for operations that are completely isolated from above.
+ /// This is used for operations whose regions are explicit capture only, i.e.
+ /// they are never allowed to implicitly reference values defined above the
+ /// parent operation.
+ IsolatedFromAbove = 0x8,
};
/// This is a "type erased" representation of a registered operation. This
return true;
}
-bool Region::isIsolatedAbove(llvm::Optional<Location> noteLoc) {
+bool Region::isIsolatedFromAbove(llvm::Optional<Location> noteLoc) {
return isRegionIsolatedAbove(*this, *this, noteLoc);
}