You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nemo.apache.org by sa...@apache.org on 2018/08/20 03:41:43 UTC

[incubator-nemo] branch master updated: [NEMO-180] Java Annotation for Prerequisite Execution Properties (#102)

This is an automated email from the ASF dual-hosted git repository.

sanha pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nemo.git


The following commit(s) were added to refs/heads/master by this push:
     new 46519a6  [NEMO-180] Java Annotation for Prerequisite Execution Properties (#102)
46519a6 is described below

commit 46519a66f546ee3f8eba0026eef82d1dc326ce75
Author: Won Wook SONG <wo...@apache.org>
AuthorDate: Mon Aug 20 12:41:41 2018 +0900

    [NEMO-180] Java Annotation for Prerequisite Execution Properties (#102)
    
    JIRA: [NEMO-180: Java Annotation for Prerequisite Execution Properties](https://issues.apache.org/jira/projects/NEMO/issues/NEMO-180)
    
    **Major changes:**
    - Applies Annotes and Requires java annotations for annotating passes and the prerequisite execution properties.
    - Implementations are changed: users can now annotate and require multiple properties together.
    
    **Minor changes to note:**
    - Fixes typo: suffle --> shuffle
    - Appropriate changes with the changes in the semantics
    
    **Tests for the changes:**
    - Existing tests check the changes
    
    **Other comments:**
    - N/A
    
    resolves [NEMO-180](https://issues.apache.org/jira/projects/NEMO/issues/NEMO-180)
---
 .../optimizer/pass/compiletime/Requires.java       | 31 ++++++++++++++++++++
 .../pass/compiletime/annotating/Annotates.java     | 31 ++++++++++++++++++++
 .../compiletime/annotating/AnnotatingPass.java     | 34 ++++++++++------------
 .../annotating/ClonedSchedulingPass.java           |  5 ++--
 .../compiletime/annotating/CompressionPass.java    |  6 ++--
 .../compiletime/annotating/DecompressionPass.java  |  5 +++-
 .../annotating/DefaultDataPersistencePass.java     |  7 +++--
 .../annotating/DefaultDataStorePass.java           |  5 ++--
 .../annotating/DefaultEdgeDecoderPass.java         |  3 +-
 .../annotating/DefaultEdgeEncoderPass.java         |  3 +-
 .../compiletime/annotating/DefaultMetricPass.java  |  3 +-
 .../annotating/DefaultParallelismPass.java         |  6 ++--
 .../annotating/DefaultScheduleGroupPass.java       | 10 +++----
 .../DisaggregationEdgeDataStorePass.java           |  6 ++--
 .../annotating/DuplicateEdgeGroupSizePass.java     |  3 +-
 ...nPass.java => LargeShuffleCompressionPass.java} | 10 ++++---
 .../annotating/LargeShuffleDataFlowPass.java       |  6 ++--
 .../LargeShuffleDataPersistencePass.java           |  7 +++--
 .../annotating/LargeShuffleDataStorePass.java      |  7 +++--
 .../annotating/LargeShuffleDecoderPass.java        |  6 ++--
 .../annotating/LargeShuffleDecompressionPass.java  |  6 ++--
 .../annotating/LargeShuffleEncoderPass.java        |  6 ++--
 .../annotating/LargeShufflePartitionerPass.java    |  6 ++--
 .../annotating/LargeShuffleResourceSlotPass.java   | 10 +++++--
 .../annotating/ResourceLocalityPass.java           |  3 +-
 .../compiletime/annotating/ResourceSitePass.java   |  5 +++-
 .../compiletime/annotating/ResourceSlotPass.java   |  3 +-
 .../annotating/ShuffleEdgePushPass.java            |  6 ++--
 .../compiletime/annotating/SkewDataStorePass.java  |  3 +-
 .../annotating/SkewMetricCollectionPass.java       |  7 +++--
 .../annotating/SkewPartitionerPass.java            |  6 ++--
 .../annotating/SkewResourceSkewedDataPass.java     |  3 +-
 .../annotating/TransientResourceDataFlowPass.java  |  6 ++--
 .../annotating/TransientResourceDataStorePass.java |  6 ++--
 .../annotating/TransientResourcePriorityPass.java  |  6 ++--
 .../pass/compiletime/composite/CompositePass.java  |  2 +-
 .../composite/LargeShuffleCompositePass.java       |  2 +-
 .../CommonSubexpressionEliminationPass.java        |  4 ++-
 .../reshaping/LargeShuffleRelayReshapingPass.java  |  6 ++--
 .../compiletime/reshaping/LoopExtractionPass.java  |  4 ++-
 .../compiletime/reshaping/LoopOptimizations.java   |  7 +++--
 .../compiletime/reshaping/LoopUnrollingPass.java   |  7 +++++
 .../pass/compiletime/reshaping/ReshapingPass.java  | 17 +++++------
 .../compiletime/reshaping/SkewReshapingPass.java   |  5 ++--
 .../compiler/optimizer/policy/PolicyBuilder.java   |  2 +-
 .../annotating/DefaultEdgeCoderPassTest.java       |  5 ++--
 .../annotating/DefaultParallelismPassTest.java     |  3 +-
 .../annotating/DefaultScheduleGroupPassTest.java   |  2 +-
 .../composite/SkewCompositePassTest.java           |  2 +-
 49 files changed, 230 insertions(+), 114 deletions(-)

diff --git a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/Requires.java b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/Requires.java
new file mode 100644
index 0000000..1283cf1
--- /dev/null
+++ b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/Requires.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2018 Seoul National University
+ *
+ * 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.
+ */
+
+package edu.snu.nemo.compiler.optimizer.pass.compiletime;
+
+import edu.snu.nemo.common.ir.executionproperty.ExecutionProperty;
+
+import java.lang.annotation.*;
+
+/**
+ * Annotation used to indicate which execution properties the class requires as prerequisites.
+ */
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+public @interface Requires {
+  Class<? extends ExecutionProperty>[] value() default {};
+}
diff --git a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/Annotates.java b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/Annotates.java
new file mode 100644
index 0000000..cf96224
--- /dev/null
+++ b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/Annotates.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2018 Seoul National University
+ *
+ * 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.
+ */
+
+package edu.snu.nemo.compiler.optimizer.pass.compiletime.annotating;
+
+import edu.snu.nemo.common.ir.executionproperty.ExecutionProperty;
+
+import java.lang.annotation.*;
+
+/**
+ * Annotation used to indicate which execution properties the class annotates.
+ */
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Inherited
+public @interface Annotates {
+  Class<? extends ExecutionProperty>[] value() default {};
+}
diff --git a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/AnnotatingPass.java b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/AnnotatingPass.java
index 3fcb7bd..c60d4f2 100644
--- a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/AnnotatingPass.java
+++ b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/AnnotatingPass.java
@@ -17,8 +17,10 @@ package edu.snu.nemo.compiler.optimizer.pass.compiletime.annotating;
 
 import edu.snu.nemo.common.ir.executionproperty.ExecutionProperty;
 import edu.snu.nemo.compiler.optimizer.pass.compiletime.CompileTimePass;
+import edu.snu.nemo.compiler.optimizer.pass.compiletime.Requires;
 
-import java.util.Collections;
+import java.util.Arrays;
+import java.util.HashSet;
 import java.util.Set;
 
 /**
@@ -26,34 +28,28 @@ import java.util.Set;
  * It is ensured by the compiler that the shape of the IR DAG itself is not modified by an AnnotatingPass.
  */
 public abstract class AnnotatingPass extends CompileTimePass {
-  private final Class<? extends ExecutionProperty> keyOfExecutionPropertyToModify;
+  private final Set<Class<? extends ExecutionProperty>> executionPropertiesToAnnotate;
   private final Set<Class<? extends ExecutionProperty>> prerequisiteExecutionProperties;
 
   /**
    * Constructor.
-   * @param keyOfExecutionPropertyToModify key of execution property to modify.
-   * @param prerequisiteExecutionProperties prerequisite execution properties.
+   * @param cls the annotating pass class.
    */
-  public AnnotatingPass(final Class<? extends ExecutionProperty> keyOfExecutionPropertyToModify,
-                        final Set<Class<? extends ExecutionProperty>> prerequisiteExecutionProperties) {
-    this.keyOfExecutionPropertyToModify = keyOfExecutionPropertyToModify;
-    this.prerequisiteExecutionProperties = prerequisiteExecutionProperties;
-  }
+  public AnnotatingPass(final Class<? extends AnnotatingPass> cls) {
+    final Annotates annotates = cls.getAnnotation(Annotates.class);
+    this.executionPropertiesToAnnotate = new HashSet<>(Arrays.asList(annotates.value()));
 
-  /**
-   * Constructor.
-   * @param keyOfExecutionPropertyToModify key of execution property to modify.
-   */
-  public AnnotatingPass(final Class<? extends ExecutionProperty> keyOfExecutionPropertyToModify) {
-    this(keyOfExecutionPropertyToModify, Collections.emptySet());
+    final Requires requires = cls.getAnnotation(Requires.class);
+    this.prerequisiteExecutionProperties = requires == null
+        ? new HashSet<>() : new HashSet<>(Arrays.asList(requires.value()));
   }
 
   /**
-   * Getter for key of execution property to modify.
-   * @return key of execution property to modify.
+   * Getter for the execution properties to annotate through the pass.
+   * @return key of execution properties to annotate through the pass.
    */
-  public final Class<? extends ExecutionProperty> getExecutionPropertyToModify() {
-    return keyOfExecutionPropertyToModify;
+  public final Set<Class<? extends ExecutionProperty>> getExecutionPropertiesToAnnotate() {
+    return executionPropertiesToAnnotate;
   }
 
   @Override
diff --git a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/ClonedSchedulingPass.java b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/ClonedSchedulingPass.java
index f808002..32797eb 100644
--- a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/ClonedSchedulingPass.java
+++ b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/ClonedSchedulingPass.java
@@ -20,17 +20,16 @@ import edu.snu.nemo.common.ir.edge.IREdge;
 import edu.snu.nemo.common.ir.vertex.IRVertex;
 import edu.snu.nemo.common.ir.vertex.executionproperty.ClonedSchedulingProperty;
 
-import java.util.Collections;
-
 /**
  * Set the ClonedScheduling property of source vertices.
  */
+@Annotates(ClonedSchedulingProperty.class)
 public final class ClonedSchedulingPass extends AnnotatingPass {
   /**
    * Default constructor.
    */
   public ClonedSchedulingPass() {
-    super(ClonedSchedulingProperty.class, Collections.emptySet());
+    super(ClonedSchedulingPass.class);
   }
 
   @Override
diff --git a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/CompressionPass.java b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/CompressionPass.java
index 0c84203..2dcd04b 100644
--- a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/CompressionPass.java
+++ b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/CompressionPass.java
@@ -24,6 +24,7 @@ import edu.snu.nemo.common.ir.vertex.IRVertex;
 /**
  * A pass for applying compression algorithm for data flowing between vertices.
  */
+@Annotates(CompressionProperty.class)
 public final class CompressionPass extends AnnotatingPass {
   private final CompressionProperty.Value compression;
 
@@ -31,8 +32,7 @@ public final class CompressionPass extends AnnotatingPass {
    * Default constructor. Uses LZ4 as default.
    */
   public CompressionPass() {
-    super(CompressionProperty.class);
-    this.compression = CompressionProperty.Value.LZ4;
+    this(CompressionProperty.Value.LZ4);
   }
 
   /**
@@ -40,7 +40,7 @@ public final class CompressionPass extends AnnotatingPass {
    * @param compression Compression to apply on edges.
    */
   public CompressionPass(final CompressionProperty.Value compression) {
-    super(CompressionProperty.class);
+    super(CompressionPass.class);
     this.compression = compression;
   }
 
diff --git a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/DecompressionPass.java b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/DecompressionPass.java
index 6283071..dc5f733 100644
--- a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/DecompressionPass.java
+++ b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/DecompressionPass.java
@@ -20,19 +20,22 @@ import edu.snu.nemo.common.ir.edge.IREdge;
 import edu.snu.nemo.common.ir.edge.executionproperty.CompressionProperty;
 import edu.snu.nemo.common.ir.edge.executionproperty.DecompressionProperty;
 import edu.snu.nemo.common.ir.vertex.IRVertex;
+import edu.snu.nemo.compiler.optimizer.pass.compiletime.Requires;
 
 
 /**
  * A pass for applying decompression algorithm for data flowing between vertices.
  * It always
  */
+@Annotates(CompressionProperty.class)
+@Requires(CompressionProperty.class)
 public final class DecompressionPass extends AnnotatingPass {
 
   /**
    * Constructor.
    */
   public DecompressionPass() {
-    super(CompressionProperty.class);
+    super(DecompressionPass.class);
   }
 
   @Override
diff --git a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/DefaultDataPersistencePass.java b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/DefaultDataPersistencePass.java
index 8f96da5..a89369e 100644
--- a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/DefaultDataPersistencePass.java
+++ b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/DefaultDataPersistencePass.java
@@ -20,19 +20,20 @@ import edu.snu.nemo.common.ir.edge.IREdge;
 import edu.snu.nemo.common.ir.edge.executionproperty.DataStoreProperty;
 import edu.snu.nemo.common.ir.edge.executionproperty.DataPersistenceProperty;
 import edu.snu.nemo.common.ir.vertex.IRVertex;
-
-import java.util.Collections;
+import edu.snu.nemo.compiler.optimizer.pass.compiletime.Requires;
 
 /**
  * Pass for initiating IREdge data persistence ExecutionProperty with default values.
  */
+@Annotates(DataPersistenceProperty.class)
+@Requires(DataStoreProperty.class)
 public final class DefaultDataPersistencePass extends AnnotatingPass {
 
   /**
    * Default constructor.
    */
   public DefaultDataPersistencePass() {
-    super(DataPersistenceProperty.class, Collections.singleton(DataStoreProperty.class));
+    super(DefaultDataPersistencePass.class);
   }
 
   @Override
diff --git a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/DefaultDataStorePass.java b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/DefaultDataStorePass.java
index e40b95a..79018dc 100644
--- a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/DefaultDataStorePass.java
+++ b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/DefaultDataStorePass.java
@@ -20,17 +20,16 @@ import edu.snu.nemo.common.ir.edge.IREdge;
 import edu.snu.nemo.common.ir.edge.executionproperty.DataStoreProperty;
 import edu.snu.nemo.common.ir.vertex.IRVertex;
 
-import java.util.Collections;
-
 /**
  * Edge data store pass to process inter-stage memory store edges.
  */
+@Annotates(DataStoreProperty.class)
 public final class DefaultDataStorePass extends AnnotatingPass {
   /**
    * Default constructor.
    */
   public DefaultDataStorePass() {
-    super(DataStoreProperty.class, Collections.emptySet());
+    super(DefaultDataStorePass.class);
   }
 
   @Override
diff --git a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/DefaultEdgeDecoderPass.java b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/DefaultEdgeDecoderPass.java
index 2283bfb..3c40c56 100644
--- a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/DefaultEdgeDecoderPass.java
+++ b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/DefaultEdgeDecoderPass.java
@@ -24,6 +24,7 @@ import edu.snu.nemo.common.ir.vertex.IRVertex;
 /**
  * Pass for initiating IREdge Decoder ExecutionProperty with default dummy coder.
  */
+@Annotates(DecoderProperty.class)
 public final class DefaultEdgeDecoderPass extends AnnotatingPass {
 
   private static final DecoderProperty DEFAULT_DECODER_PROPERTY =
@@ -33,7 +34,7 @@ public final class DefaultEdgeDecoderPass extends AnnotatingPass {
    * Default constructor.
    */
   public DefaultEdgeDecoderPass() {
-    super(DecoderProperty.class);
+    super(DefaultEdgeDecoderPass.class);
   }
 
   @Override
diff --git a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/DefaultEdgeEncoderPass.java b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/DefaultEdgeEncoderPass.java
index 0238c72..a13a1f2 100644
--- a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/DefaultEdgeEncoderPass.java
+++ b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/DefaultEdgeEncoderPass.java
@@ -24,6 +24,7 @@ import edu.snu.nemo.common.ir.vertex.IRVertex;
 /**
  * Pass for initiating IREdge Encoder ExecutionProperty with default dummy coder.
  */
+@Annotates(EncoderProperty.class)
 public final class DefaultEdgeEncoderPass extends AnnotatingPass {
 
   private static final EncoderProperty DEFAULT_DECODER_PROPERTY =
@@ -33,7 +34,7 @@ public final class DefaultEdgeEncoderPass extends AnnotatingPass {
    * Default constructor.
    */
   public DefaultEdgeEncoderPass() {
-    super(EncoderProperty.class);
+    super(DefaultEdgeEncoderPass.class);
   }
 
   @Override
diff --git a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/DefaultMetricPass.java b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/DefaultMetricPass.java
index c96ac0b..e13b15e 100644
--- a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/DefaultMetricPass.java
+++ b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/DefaultMetricPass.java
@@ -31,12 +31,13 @@ import java.util.Map;
 /**
  * Pass for initiating IREdge Metric ExecutionProperty with default key range.
  */
+@Annotates(DataSkewMetricProperty.class)
 public final class DefaultMetricPass extends AnnotatingPass {
   /**
    * Default constructor.
    */
   public DefaultMetricPass() {
-    super(DataSkewMetricProperty.class);
+    super(DefaultMetricPass.class);
   }
 
   @Override
diff --git a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/DefaultParallelismPass.java b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/DefaultParallelismPass.java
index 8b85454..87cc71a 100644
--- a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/DefaultParallelismPass.java
+++ b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/DefaultParallelismPass.java
@@ -22,13 +22,15 @@ import edu.snu.nemo.common.ir.vertex.IRVertex;
 import edu.snu.nemo.common.ir.vertex.SourceVertex;
 import edu.snu.nemo.common.dag.DAG;
 import edu.snu.nemo.common.ir.vertex.executionproperty.ParallelismProperty;
+import edu.snu.nemo.compiler.optimizer.pass.compiletime.Requires;
 
-import java.util.Collections;
 import java.util.List;
 
 /**
  * Optimization pass for tagging parallelism execution property.
  */
+@Annotates(ParallelismProperty.class)
+@Requires(CommunicationPatternProperty.class)
 public final class DefaultParallelismPass extends AnnotatingPass {
   private final int desiredSourceParallelism;
   // we decrease the number of parallelism by this number on each shuffle boundary.
@@ -49,7 +51,7 @@ public final class DefaultParallelismPass extends AnnotatingPass {
    */
   public DefaultParallelismPass(final int desiredSourceParallelism,
                                 final int shuffleDecreaseFactor) {
-    super(ParallelismProperty.class, Collections.singleton(CommunicationPatternProperty.class));
+    super(DefaultParallelismPass.class);
     this.desiredSourceParallelism = desiredSourceParallelism;
     this.shuffleDecreaseFactor = shuffleDecreaseFactor;
   }
diff --git a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/DefaultScheduleGroupPass.java b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/DefaultScheduleGroupPass.java
index 4dbf455..53dd17e 100644
--- a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/DefaultScheduleGroupPass.java
+++ b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/DefaultScheduleGroupPass.java
@@ -24,11 +24,10 @@ import edu.snu.nemo.common.ir.edge.executionproperty.CommunicationPatternPropert
 import edu.snu.nemo.common.ir.vertex.IRVertex;
 import edu.snu.nemo.common.ir.edge.executionproperty.DataFlowProperty;
 import edu.snu.nemo.common.ir.vertex.executionproperty.ScheduleGroupProperty;
+import edu.snu.nemo.compiler.optimizer.pass.compiletime.Requires;
 import org.apache.commons.lang3.mutable.MutableInt;
 
 import java.util.*;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
 
 /**
  * A pass for assigning each stages in schedule groups.
@@ -49,6 +48,8 @@ import java.util.stream.Stream;
  *   </li>
  * </ul>
  */
+@Annotates(ScheduleGroupProperty.class)
+@Requires({CommunicationPatternProperty.class, DataFlowProperty.class})
 public final class DefaultScheduleGroupPass extends AnnotatingPass {
 
   private final boolean allowBroadcastWithinScheduleGroup;
@@ -71,10 +72,7 @@ public final class DefaultScheduleGroupPass extends AnnotatingPass {
   public DefaultScheduleGroupPass(final boolean allowBroadcastWithinScheduleGroup,
                                   final boolean allowShuffleWithinScheduleGroup,
                                   final boolean allowMultipleInEdgesWithinScheduleGroup) {
-    super(ScheduleGroupProperty.class, Stream.of(
-        CommunicationPatternProperty.class,
-        DataFlowProperty.class
-    ).collect(Collectors.toSet()));
+    super(DefaultScheduleGroupPass.class);
     this.allowBroadcastWithinScheduleGroup = allowBroadcastWithinScheduleGroup;
     this.allowShuffleWithinScheduleGroup = allowShuffleWithinScheduleGroup;
     this.allowMultipleInEdgesWithinScheduleGroup = allowMultipleInEdgesWithinScheduleGroup;
diff --git a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/DisaggregationEdgeDataStorePass.java b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/DisaggregationEdgeDataStorePass.java
index 262f0ca..9122dc0 100644
--- a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/DisaggregationEdgeDataStorePass.java
+++ b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/DisaggregationEdgeDataStorePass.java
@@ -19,20 +19,22 @@ import edu.snu.nemo.common.ir.edge.IREdge;
 import edu.snu.nemo.common.ir.edge.executionproperty.DataStoreProperty;
 import edu.snu.nemo.common.ir.vertex.IRVertex;
 import edu.snu.nemo.common.dag.DAG;
+import edu.snu.nemo.compiler.optimizer.pass.compiletime.Requires;
 
-import java.util.Collections;
 import java.util.List;
 
 /**
  * A pass to support Disaggregated Resources by tagging edges.
  * This pass handles the DataStore ExecutionProperty.
  */
+@Annotates(DataStoreProperty.class)
+@Requires(DataStoreProperty.class)
 public final class DisaggregationEdgeDataStorePass extends AnnotatingPass {
   /**
    * Default constructor.
    */
   public DisaggregationEdgeDataStorePass() {
-    super(DataStoreProperty.class, Collections.singleton(DataStoreProperty.class));
+    super(DisaggregationEdgeDataStorePass.class);
   }
 
   @Override
diff --git a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/DuplicateEdgeGroupSizePass.java b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/DuplicateEdgeGroupSizePass.java
index c4db802..8dbe725 100644
--- a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/DuplicateEdgeGroupSizePass.java
+++ b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/DuplicateEdgeGroupSizePass.java
@@ -27,13 +27,14 @@ import java.util.Optional;
 /**
  * A pass for annotate duplicate data for each edge.
  */
+@Annotates(DuplicateEdgeGroupProperty.class)
 public final class DuplicateEdgeGroupSizePass extends AnnotatingPass {
 
   /**
    * Default constructor.
    */
   public DuplicateEdgeGroupSizePass() {
-    super(DuplicateEdgeGroupProperty.class);
+    super(DuplicateEdgeGroupSizePass.class);
   }
 
   @Override
diff --git a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/LargeSuffleCompressionPass.java b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/LargeShuffleCompressionPass.java
similarity index 86%
rename from compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/LargeSuffleCompressionPass.java
rename to compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/LargeShuffleCompressionPass.java
index 08ede72..ae9044e 100644
--- a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/LargeSuffleCompressionPass.java
+++ b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/LargeShuffleCompressionPass.java
@@ -20,8 +20,8 @@ import edu.snu.nemo.common.ir.edge.IREdge;
 import edu.snu.nemo.common.ir.edge.executionproperty.CommunicationPatternProperty;
 import edu.snu.nemo.common.ir.edge.executionproperty.CompressionProperty;
 import edu.snu.nemo.common.ir.vertex.IRVertex;
+import edu.snu.nemo.compiler.optimizer.pass.compiletime.Requires;
 
-import java.util.Collections;
 import java.util.List;
 
 /**
@@ -29,12 +29,14 @@ import java.util.List;
  * This pass modifies the encoder property toward {@link edu.snu.nemo.common.ir.vertex.transform.RelayTransform}
  * to write data as byte arrays.
  */
-public final class LargeSuffleCompressionPass extends AnnotatingPass {
+@Annotates(CompressionProperty.class)
+@Requires(CommunicationPatternProperty.class)
+public final class LargeShuffleCompressionPass extends AnnotatingPass {
   /**
    * Default constructor.
    */
-  public LargeSuffleCompressionPass() {
-    super(CompressionProperty.class, Collections.singleton(CommunicationPatternProperty.class));
+  public LargeShuffleCompressionPass() {
+    super(LargeShuffleCompressionPass.class);
   }
 
   @Override
diff --git a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/LargeShuffleDataFlowPass.java b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/LargeShuffleDataFlowPass.java
index d5d18ac..6a623a0 100644
--- a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/LargeShuffleDataFlowPass.java
+++ b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/LargeShuffleDataFlowPass.java
@@ -20,20 +20,22 @@ import edu.snu.nemo.common.ir.edge.IREdge;
 import edu.snu.nemo.common.ir.edge.executionproperty.CommunicationPatternProperty;
 import edu.snu.nemo.common.ir.edge.executionproperty.DataFlowProperty;
 import edu.snu.nemo.common.ir.vertex.IRVertex;
+import edu.snu.nemo.compiler.optimizer.pass.compiletime.Requires;
 
-import java.util.Collections;
 import java.util.List;
 
 /**
  * A pass to optimize large shuffle by tagging edges.
  * This pass handles the DataFlowModel ExecutionProperty.
  */
+@Annotates(DataFlowProperty.class)
+@Requires(CommunicationPatternProperty.class)
 public final class LargeShuffleDataFlowPass extends AnnotatingPass {
   /**
    * Default constructor.
    */
   public LargeShuffleDataFlowPass() {
-    super(DataFlowProperty.class, Collections.singleton(CommunicationPatternProperty.class));
+    super(LargeShuffleDataFlowPass.class);
   }
 
   @Override
diff --git a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/LargeShuffleDataPersistencePass.java b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/LargeShuffleDataPersistencePass.java
index d7901f2..e4e8e28 100644
--- a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/LargeShuffleDataPersistencePass.java
+++ b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/LargeShuffleDataPersistencePass.java
@@ -20,20 +20,21 @@ import edu.snu.nemo.common.ir.edge.IREdge;
 import edu.snu.nemo.common.ir.edge.executionproperty.DataFlowProperty;
 import edu.snu.nemo.common.ir.edge.executionproperty.DataPersistenceProperty;
 import edu.snu.nemo.common.ir.vertex.IRVertex;
-
-import java.util.Collections;
+import edu.snu.nemo.compiler.optimizer.pass.compiletime.Requires;
 
 /**
  * A pass to optimize large shuffle by tagging edges.
  * This pass handles the data persistence ExecutionProperty.
  */
+@Annotates(DataPersistenceProperty.class)
+@Requires(DataFlowProperty.class)
 public final class LargeShuffleDataPersistencePass extends AnnotatingPass {
 
   /**
    * Default constructor.
    */
   public LargeShuffleDataPersistencePass() {
-    super(DataPersistenceProperty.class, Collections.singleton(DataFlowProperty.class));
+    super(LargeShuffleDataPersistencePass.class);
   }
 
   @Override
diff --git a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/LargeShuffleDataStorePass.java b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/LargeShuffleDataStorePass.java
index 40b4bb4..575825b 100644
--- a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/LargeShuffleDataStorePass.java
+++ b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/LargeShuffleDataStorePass.java
@@ -20,19 +20,20 @@ import edu.snu.nemo.common.ir.edge.IREdge;
 import edu.snu.nemo.common.ir.edge.executionproperty.CommunicationPatternProperty;
 import edu.snu.nemo.common.ir.edge.executionproperty.DataStoreProperty;
 import edu.snu.nemo.common.ir.vertex.IRVertex;
-
-import java.util.Collections;
+import edu.snu.nemo.compiler.optimizer.pass.compiletime.Requires;
 
 /**
  * A pass to optimize large shuffle by tagging edges.
  * This pass handles the DataStore ExecutionProperty.
  */
+@Annotates(DataStoreProperty.class)
+@Requires(CommunicationPatternProperty.class)
 public final class LargeShuffleDataStorePass extends AnnotatingPass {
   /**
    * Default constructor.
    */
   public LargeShuffleDataStorePass() {
-    super(DataStoreProperty.class, Collections.singleton(CommunicationPatternProperty.class));
+    super(LargeShuffleDataStorePass.class);
   }
 
   @Override
diff --git a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/LargeShuffleDecoderPass.java b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/LargeShuffleDecoderPass.java
index 978aff1..c0647e3 100644
--- a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/LargeShuffleDecoderPass.java
+++ b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/LargeShuffleDecoderPass.java
@@ -21,8 +21,8 @@ import edu.snu.nemo.common.ir.edge.IREdge;
 import edu.snu.nemo.common.ir.edge.executionproperty.CommunicationPatternProperty;
 import edu.snu.nemo.common.ir.edge.executionproperty.DecoderProperty;
 import edu.snu.nemo.common.ir.vertex.IRVertex;
+import edu.snu.nemo.compiler.optimizer.pass.compiletime.Requires;
 
-import java.util.Collections;
 import java.util.List;
 
 /**
@@ -30,12 +30,14 @@ import java.util.List;
  * This pass modifies the decoder property toward {@link edu.snu.nemo.common.ir.vertex.transform.RelayTransform}
  * to read data as byte arrays.
  */
+@Annotates(DecoderProperty.class)
+@Requires(CommunicationPatternProperty.class)
 public final class LargeShuffleDecoderPass extends AnnotatingPass {
   /**
    * Default constructor.
    */
   public LargeShuffleDecoderPass() {
-    super(DecoderProperty.class, Collections.singleton(CommunicationPatternProperty.class));
+    super(LargeShuffleDecoderPass.class);
   }
 
   @Override
diff --git a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/LargeShuffleDecompressionPass.java b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/LargeShuffleDecompressionPass.java
index 625b2c9..7706c98 100644
--- a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/LargeShuffleDecompressionPass.java
+++ b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/LargeShuffleDecompressionPass.java
@@ -21,8 +21,8 @@ import edu.snu.nemo.common.ir.edge.executionproperty.CommunicationPatternPropert
 import edu.snu.nemo.common.ir.edge.executionproperty.CompressionProperty;
 import edu.snu.nemo.common.ir.edge.executionproperty.DecompressionProperty;
 import edu.snu.nemo.common.ir.vertex.IRVertex;
+import edu.snu.nemo.compiler.optimizer.pass.compiletime.Requires;
 
-import java.util.Collections;
 import java.util.List;
 
 /**
@@ -30,12 +30,14 @@ import java.util.List;
  * This pass modifies the decoder property toward {@link edu.snu.nemo.common.ir.vertex.transform.RelayTransform}
  * to read data as byte arrays.
  */
+@Annotates(DecompressionProperty.class)
+@Requires(CommunicationPatternProperty.class)
 public final class LargeShuffleDecompressionPass extends AnnotatingPass {
   /**
    * Default constructor.
    */
   public LargeShuffleDecompressionPass() {
-    super(DecompressionProperty.class, Collections.singleton(CommunicationPatternProperty.class));
+    super(LargeShuffleDecompressionPass.class);
   }
 
   @Override
diff --git a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/LargeShuffleEncoderPass.java b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/LargeShuffleEncoderPass.java
index 43def8b..bd15052 100644
--- a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/LargeShuffleEncoderPass.java
+++ b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/LargeShuffleEncoderPass.java
@@ -21,8 +21,8 @@ import edu.snu.nemo.common.ir.edge.IREdge;
 import edu.snu.nemo.common.ir.edge.executionproperty.CommunicationPatternProperty;
 import edu.snu.nemo.common.ir.edge.executionproperty.EncoderProperty;
 import edu.snu.nemo.common.ir.vertex.IRVertex;
+import edu.snu.nemo.compiler.optimizer.pass.compiletime.Requires;
 
-import java.util.Collections;
 import java.util.List;
 
 /**
@@ -30,12 +30,14 @@ import java.util.List;
  * This pass modifies the encoder property toward {@link edu.snu.nemo.common.ir.vertex.transform.RelayTransform}
  * to write data as byte arrays.
  */
+@Annotates(EncoderProperty.class)
+@Requires(CommunicationPatternProperty.class)
 public final class LargeShuffleEncoderPass extends AnnotatingPass {
   /**
    * Default constructor.
    */
   public LargeShuffleEncoderPass() {
-    super(EncoderProperty.class, Collections.singleton(CommunicationPatternProperty.class));
+    super(LargeShuffleEncoderPass.class);
   }
 
   @Override
diff --git a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/LargeShufflePartitionerPass.java b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/LargeShufflePartitionerPass.java
index 084ab62..e191ff7 100644
--- a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/LargeShufflePartitionerPass.java
+++ b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/LargeShufflePartitionerPass.java
@@ -20,8 +20,8 @@ import edu.snu.nemo.common.ir.edge.IREdge;
 import edu.snu.nemo.common.ir.edge.executionproperty.CommunicationPatternProperty;
 import edu.snu.nemo.common.ir.edge.executionproperty.PartitionerProperty;
 import edu.snu.nemo.common.ir.vertex.IRVertex;
+import edu.snu.nemo.compiler.optimizer.pass.compiletime.Requires;
 
-import java.util.Collections;
 import java.util.List;
 
 /**
@@ -31,12 +31,14 @@ import java.util.List;
  * This enables that every byte[] element, which was a partition for the reduce task, becomes one partition again
  * and flushed to disk write after it is relayed.
  */
+@Annotates(PartitionerProperty.class)
+@Requires(CommunicationPatternProperty.class)
 public final class LargeShufflePartitionerPass extends AnnotatingPass {
   /**
    * Default constructor.
    */
   public LargeShufflePartitionerPass() {
-    super(PartitionerProperty.class, Collections.singleton(CommunicationPatternProperty.class));
+    super(LargeShufflePartitionerPass.class);
   }
 
   @Override
diff --git a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/LargeShuffleResourceSlotPass.java b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/LargeShuffleResourceSlotPass.java
index f474629..efce189 100644
--- a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/LargeShuffleResourceSlotPass.java
+++ b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/LargeShuffleResourceSlotPass.java
@@ -20,16 +20,20 @@ import edu.snu.nemo.common.ir.edge.IREdge;
 import edu.snu.nemo.common.ir.edge.executionproperty.DataFlowProperty;
 import edu.snu.nemo.common.ir.vertex.IRVertex;
 import edu.snu.nemo.common.ir.vertex.executionproperty.ResourceSlotProperty;
-
-import java.util.Collections;
+import edu.snu.nemo.compiler.optimizer.pass.compiletime.Requires;
 
 /**
  * Sets {@link ResourceSlotProperty}.
  */
+@Annotates(ResourceSlotProperty.class)
+@Requires(DataFlowProperty.class)
 public final class LargeShuffleResourceSlotPass extends AnnotatingPass {
 
+  /**
+   * Default constructor.
+   */
   public LargeShuffleResourceSlotPass() {
-    super(ResourceSlotProperty.class, Collections.singleton(DataFlowProperty.class));
+    super(LargeShuffleResourceSlotPass.class);
   }
 
   @Override
diff --git a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/ResourceLocalityPass.java b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/ResourceLocalityPass.java
index 53f23df..9884808 100644
--- a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/ResourceLocalityPass.java
+++ b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/ResourceLocalityPass.java
@@ -23,10 +23,11 @@ import edu.snu.nemo.common.ir.vertex.executionproperty.ResourceLocalityProperty;
 /**
  * Sets {@link ResourceLocalityProperty}.
  */
+@Annotates(ResourceLocalityProperty.class)
 public final class ResourceLocalityPass extends AnnotatingPass {
 
   public ResourceLocalityPass() {
-    super(ResourceLocalityProperty.class);
+    super(ResourceLocalityPass.class);
   }
 
   @Override
diff --git a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/ResourceSitePass.java b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/ResourceSitePass.java
index 005138c..5883ac1 100644
--- a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/ResourceSitePass.java
+++ b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/ResourceSitePass.java
@@ -23,6 +23,7 @@ import edu.snu.nemo.common.ir.edge.executionproperty.CommunicationPatternPropert
 import edu.snu.nemo.common.ir.vertex.IRVertex;
 import edu.snu.nemo.common.ir.vertex.executionproperty.ResourceSiteProperty;
 import edu.snu.nemo.common.ir.vertex.executionproperty.ParallelismProperty;
+import edu.snu.nemo.compiler.optimizer.pass.compiletime.Requires;
 import org.apache.commons.math3.optim.BaseOptimizer;
 import org.apache.commons.math3.optim.PointValuePair;
 import org.apache.commons.math3.optim.linear.*;
@@ -50,6 +51,8 @@ import java.util.*;
  * Also, this pass assumes network bandwidth to be the bottleneck. Each node should have enough capacity to run
  * TaskGroups immediately as scheduler attempts to schedule a TaskGroup.
  */
+@Annotates(ResourceSiteProperty.class)
+@Requires(ParallelismProperty.class)
 public final class ResourceSitePass extends AnnotatingPass {
 
   // Index of the objective parameter, in the coefficient vector
@@ -64,7 +67,7 @@ public final class ResourceSitePass extends AnnotatingPass {
    * Default constructor.
    */
   public ResourceSitePass() {
-    super(ResourceSiteProperty.class, Collections.singleton(ParallelismProperty.class));
+    super(ResourceSitePass.class);
   }
 
   @Override
diff --git a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/ResourceSlotPass.java b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/ResourceSlotPass.java
index f971882..bbb3fc6 100644
--- a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/ResourceSlotPass.java
+++ b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/ResourceSlotPass.java
@@ -23,10 +23,11 @@ import edu.snu.nemo.common.ir.vertex.executionproperty.ResourceSlotProperty;
 /**
  * Sets {@link ResourceSlotProperty}.
  */
+@Annotates(ResourceSlotProperty.class)
 public final class ResourceSlotPass extends AnnotatingPass {
 
   public ResourceSlotPass() {
-    super(ResourceSlotProperty.class);
+    super(ResourceSlotPass.class);
   }
 
   @Override
diff --git a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/ShuffleEdgePushPass.java b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/ShuffleEdgePushPass.java
index feff84f..0820dde 100644
--- a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/ShuffleEdgePushPass.java
+++ b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/ShuffleEdgePushPass.java
@@ -20,20 +20,22 @@ import edu.snu.nemo.common.ir.edge.IREdge;
 import edu.snu.nemo.common.ir.edge.executionproperty.CommunicationPatternProperty;
 import edu.snu.nemo.common.ir.edge.executionproperty.DataFlowProperty;
 import edu.snu.nemo.common.ir.vertex.IRVertex;
+import edu.snu.nemo.compiler.optimizer.pass.compiletime.Requires;
 
-import java.util.Collections;
 import java.util.List;
 
 /**
  * A pass for tagging shuffle edges different from the default ones.
  * It sets DataFlowModel ExecutionProperty as "push".
  */
+@Annotates(DataFlowProperty.class)
+@Requires(CommunicationPatternProperty.class)
 public final class ShuffleEdgePushPass extends AnnotatingPass {
   /**
    * Default constructor.
    */
   public ShuffleEdgePushPass() {
-    super(DataFlowProperty.class, Collections.singleton(CommunicationPatternProperty.class));
+    super(ShuffleEdgePushPass.class);
   }
 
   @Override
diff --git a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/SkewDataStorePass.java b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/SkewDataStorePass.java
index 8b1592b..984e8df 100644
--- a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/SkewDataStorePass.java
+++ b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/SkewDataStorePass.java
@@ -26,12 +26,13 @@ import edu.snu.nemo.common.ir.vertex.MetricCollectionBarrierVertex;
  * It specifies the incoming one-to-one edges to MetricCollectionVertices to have either MemoryStore or LocalFileStore
  * as its DataStore ExecutionProperty.
  */
+@Annotates(DataStoreProperty.class)
 public final class SkewDataStorePass extends AnnotatingPass {
   /**
    * Default constructor.
    */
   public SkewDataStorePass() {
-    super(DataStoreProperty.class);
+    super(SkewDataStorePass.class);
   }
 
   @Override
diff --git a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/SkewMetricCollectionPass.java b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/SkewMetricCollectionPass.java
index f2bf9d3..ad635c6 100644
--- a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/SkewMetricCollectionPass.java
+++ b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/SkewMetricCollectionPass.java
@@ -21,20 +21,21 @@ import edu.snu.nemo.common.ir.edge.executionproperty.CommunicationPatternPropert
 import edu.snu.nemo.common.ir.vertex.IRVertex;
 import edu.snu.nemo.common.ir.vertex.MetricCollectionBarrierVertex;
 import edu.snu.nemo.common.ir.edge.executionproperty.MetricCollectionProperty;
-
-import java.util.Collections;
+import edu.snu.nemo.compiler.optimizer.pass.compiletime.Requires;
 
 /**
  * Pass to annotate the DAG for a job to perform data skew.
  * It specifies the outgoing Shuffle edges from MetricCollectionVertices with a MetricCollection ExecutionProperty
  * which lets the edge to know what metric collection it should perform.
  */
+@Annotates(MetricCollectionProperty.class)
+@Requires(CommunicationPatternProperty.class)
 public final class SkewMetricCollectionPass extends AnnotatingPass {
   /**
    * Default constructor.
    */
   public SkewMetricCollectionPass() {
-    super(MetricCollectionProperty.class, Collections.singleton(CommunicationPatternProperty.class));
+    super(SkewMetricCollectionPass.class);
   }
 
   @Override
diff --git a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/SkewPartitionerPass.java b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/SkewPartitionerPass.java
index 58c785f..7ffd221 100644
--- a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/SkewPartitionerPass.java
+++ b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/SkewPartitionerPass.java
@@ -21,19 +21,21 @@ import edu.snu.nemo.common.ir.edge.executionproperty.MetricCollectionProperty;
 import edu.snu.nemo.common.ir.vertex.IRVertex;
 import edu.snu.nemo.common.ir.vertex.MetricCollectionBarrierVertex;
 import edu.snu.nemo.common.ir.edge.executionproperty.PartitionerProperty;
+import edu.snu.nemo.compiler.optimizer.pass.compiletime.Requires;
 
-import java.util.Collections;
 import java.util.List;
 
 /**
  * Transient resource pass for tagging edges with {@link PartitionerProperty}.
  */
+@Annotates(PartitionerProperty.class)
+@Requires(MetricCollectionProperty.class)
 public final class SkewPartitionerPass extends AnnotatingPass {
   /**
    * Default constructor.
    */
   public SkewPartitionerPass() {
-    super(PartitionerProperty.class, Collections.singleton(MetricCollectionProperty.class));
+    super(SkewPartitionerPass.class);
   }
 
   @Override
diff --git a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/SkewResourceSkewedDataPass.java b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/SkewResourceSkewedDataPass.java
index c5bc1d9..c3739af 100644
--- a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/SkewResourceSkewedDataPass.java
+++ b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/SkewResourceSkewedDataPass.java
@@ -28,12 +28,13 @@ import java.util.List;
  * Pass to annotate the DAG for a job to perform data skew.
  * It specifies which optimization to perform on the MetricCollectionBarrierVertex.
  */
+@Annotates(DynamicOptimizationProperty.class)
 public final class SkewResourceSkewedDataPass extends AnnotatingPass {
   /**
    * Default constructor.
    */
   public SkewResourceSkewedDataPass() {
-    super(DynamicOptimizationProperty.class);
+    super(SkewResourceSkewedDataPass.class);
   }
 
   private boolean hasMetricCollectionBarrierVertexAsParent(final DAG<IRVertex, IREdge> dag,
diff --git a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/TransientResourceDataFlowPass.java b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/TransientResourceDataFlowPass.java
index 4da3bcf..9850d81 100644
--- a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/TransientResourceDataFlowPass.java
+++ b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/TransientResourceDataFlowPass.java
@@ -20,8 +20,8 @@ import edu.snu.nemo.common.ir.edge.IREdge;
 import edu.snu.nemo.common.ir.edge.executionproperty.DataFlowProperty;
 import edu.snu.nemo.common.ir.vertex.IRVertex;
 import edu.snu.nemo.common.ir.vertex.executionproperty.ResourcePriorityProperty;
+import edu.snu.nemo.compiler.optimizer.pass.compiletime.Requires;
 
-import java.util.Collections;
 import java.util.List;
 
 import static edu.snu.nemo.compiler.optimizer.pass.compiletime.annotating.TransientResourceDataStorePass.fromTransientToReserved;
@@ -29,12 +29,14 @@ import static edu.snu.nemo.compiler.optimizer.pass.compiletime.annotating.Transi
 /**
  * Push from transient resources to reserved resources.
  */
+@Annotates(DataFlowProperty.class)
+@Requires(ResourcePriorityProperty.class)
 public final class TransientResourceDataFlowPass extends AnnotatingPass {
   /**
    * Default constructor.
    */
   public TransientResourceDataFlowPass() {
-    super(DataFlowProperty.class, Collections.singleton(ResourcePriorityProperty.class));
+    super(TransientResourceDataFlowPass.class);
   }
 
   @Override
diff --git a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/TransientResourceDataStorePass.java b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/TransientResourceDataStorePass.java
index dcd9132..1f81651 100644
--- a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/TransientResourceDataStorePass.java
+++ b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/TransientResourceDataStorePass.java
@@ -21,19 +21,21 @@ import edu.snu.nemo.common.ir.edge.executionproperty.DataStoreProperty;
 import edu.snu.nemo.common.ir.vertex.IRVertex;
 import edu.snu.nemo.common.dag.DAG;
 import edu.snu.nemo.common.ir.vertex.executionproperty.ResourcePriorityProperty;
+import edu.snu.nemo.compiler.optimizer.pass.compiletime.Requires;
 
-import java.util.Collections;
 import java.util.List;
 
 /**
  * Transient resource pass for tagging edges with DataStore ExecutionProperty.
  */
+@Annotates(DataStoreProperty.class)
+@Requires(ResourcePriorityProperty.class)
 public final class TransientResourceDataStorePass extends AnnotatingPass {
   /**
    * Default constructor.
    */
   public TransientResourceDataStorePass() {
-    super(DataStoreProperty.class, Collections.singleton(ResourcePriorityProperty.class));
+    super(TransientResourceDataStorePass.class);
   }
 
   @Override
diff --git a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/TransientResourcePriorityPass.java b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/TransientResourcePriorityPass.java
index cdf25a2..177ffbd 100644
--- a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/TransientResourcePriorityPass.java
+++ b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/TransientResourcePriorityPass.java
@@ -20,19 +20,21 @@ import edu.snu.nemo.common.ir.edge.executionproperty.CommunicationPatternPropert
 import edu.snu.nemo.common.ir.vertex.IRVertex;
 import edu.snu.nemo.common.dag.DAG;
 import edu.snu.nemo.common.ir.vertex.executionproperty.ResourcePriorityProperty;
+import edu.snu.nemo.compiler.optimizer.pass.compiletime.Requires;
 
-import java.util.Collections;
 import java.util.List;
 
 /**
  * Place valuable computations on reserved resources, and the rest on transient resources.
  */
+@Annotates(ResourcePriorityProperty.class)
+@Requires(CommunicationPatternProperty.class)
 public final class TransientResourcePriorityPass extends AnnotatingPass {
   /**
    * Default constructor.
    */
   public TransientResourcePriorityPass() {
-    super(ResourcePriorityProperty.class, Collections.singleton(CommunicationPatternProperty.class));
+    super(TransientResourcePriorityPass.class);
   }
 
   @Override
diff --git a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/composite/CompositePass.java b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/composite/CompositePass.java
index 378d125..aa44e26 100644
--- a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/composite/CompositePass.java
+++ b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/composite/CompositePass.java
@@ -41,7 +41,7 @@ public abstract class CompositePass extends CompileTimePass {
     passList.forEach(pass -> prerequisiteExecutionProperties.addAll(pass.getPrerequisiteExecutionProperties()));
     passList.forEach(pass -> {
       if (pass instanceof AnnotatingPass) {
-        prerequisiteExecutionProperties.remove(((AnnotatingPass) pass).getExecutionPropertyToModify());
+        prerequisiteExecutionProperties.removeAll(((AnnotatingPass) pass).getExecutionPropertiesToAnnotate());
       }
     });
   }
diff --git a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/composite/LargeShuffleCompositePass.java b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/composite/LargeShuffleCompositePass.java
index e69e56c..8518905 100644
--- a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/composite/LargeShuffleCompositePass.java
+++ b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/composite/LargeShuffleCompositePass.java
@@ -36,7 +36,7 @@ public final class LargeShuffleCompositePass extends CompositePass {
         new LargeShuffleDecoderPass(),
         new LargeShuffleEncoderPass(),
         new LargeShufflePartitionerPass(),
-        new LargeSuffleCompressionPass(),
+        new LargeShuffleCompressionPass(),
         new LargeShuffleDecompressionPass(),
         new LargeShuffleDataPersistencePass(),
         new LargeShuffleResourceSlotPass()
diff --git a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/reshaping/CommonSubexpressionEliminationPass.java b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/reshaping/CommonSubexpressionEliminationPass.java
index 606d84b..818e1b7 100644
--- a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/reshaping/CommonSubexpressionEliminationPass.java
+++ b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/reshaping/CommonSubexpressionEliminationPass.java
@@ -26,6 +26,7 @@ import edu.snu.nemo.common.ir.vertex.OperatorVertex;
 import edu.snu.nemo.common.ir.vertex.transform.Transform;
 import edu.snu.nemo.common.dag.DAG;
 import edu.snu.nemo.common.dag.DAGBuilder;
+import edu.snu.nemo.compiler.optimizer.pass.compiletime.Requires;
 
 import java.util.*;
 import java.util.stream.Collectors;
@@ -36,12 +37,13 @@ import java.util.stream.Collectors;
  * they include the same transform, and has incoming edges from an identical set of vertices.
  * Refer to CommonSubexpressionEliminationPassTest for such cases.
  */
+@Requires(CommunicationPatternProperty.class)
 public final class CommonSubexpressionEliminationPass extends ReshapingPass {
   /**
    * Default constructor.
    */
   public CommonSubexpressionEliminationPass() {
-    super(Collections.singleton(CommunicationPatternProperty.class));
+    super(CommonSubexpressionEliminationPass.class);
   }
 
   @Override
diff --git a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/reshaping/LargeShuffleRelayReshapingPass.java b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/reshaping/LargeShuffleRelayReshapingPass.java
index 7abee7e..fa2afee 100644
--- a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/reshaping/LargeShuffleRelayReshapingPass.java
+++ b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/reshaping/LargeShuffleRelayReshapingPass.java
@@ -24,8 +24,7 @@ import edu.snu.nemo.common.ir.edge.IREdge;
 import edu.snu.nemo.common.ir.vertex.IRVertex;
 import edu.snu.nemo.common.ir.vertex.OperatorVertex;
 import edu.snu.nemo.common.ir.vertex.transform.RelayTransform;
-
-import java.util.Collections;
+import edu.snu.nemo.compiler.optimizer.pass.compiletime.Requires;
 
 /**
  * Pass to modify the DAG for a job to batch the disk seek.
@@ -33,13 +32,14 @@ import java.util.Collections;
  * receiving shuffle edges,
  * to merge the shuffled data in memory and write to the disk at once.
  */
+@Requires(CommunicationPatternProperty.class)
 public final class LargeShuffleRelayReshapingPass extends ReshapingPass {
 
   /**
    * Default constructor.
    */
   public LargeShuffleRelayReshapingPass() {
-    super(Collections.singleton(CommunicationPatternProperty.class));
+    super(LargeShuffleRelayReshapingPass.class);
   }
 
   @Override
diff --git a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/reshaping/LoopExtractionPass.java b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/reshaping/LoopExtractionPass.java
index 6c1afb2..e11d712 100644
--- a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/reshaping/LoopExtractionPass.java
+++ b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/reshaping/LoopExtractionPass.java
@@ -23,6 +23,7 @@ import edu.snu.nemo.common.dag.DAGBuilder;
 import edu.snu.nemo.common.ir.vertex.LoopVertex;
 import edu.snu.nemo.common.ir.vertex.OperatorVertex;
 import edu.snu.nemo.common.ir.vertex.SourceVertex;
+import edu.snu.nemo.compiler.optimizer.pass.compiletime.Requires;
 
 import java.util.*;
 
@@ -32,12 +33,13 @@ import java.util.*;
  * Then, it rolls repetitive operators into one root LoopOperator, which contains enough information to produce all
  * other iterative computations.
  */
+@Requires(CommunicationPatternProperty.class)
 public final class LoopExtractionPass extends ReshapingPass {
   /**
    * Default constructor.
    */
   public LoopExtractionPass() {
-    super(Collections.singleton(CommunicationPatternProperty.class));
+    super(LoopExtractionPass.class);
   }
 
   @Override
diff --git a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/reshaping/LoopOptimizations.java b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/reshaping/LoopOptimizations.java
index 4dc53ac..9d9f8bc 100644
--- a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/reshaping/LoopOptimizations.java
+++ b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/reshaping/LoopOptimizations.java
@@ -23,6 +23,7 @@ import edu.snu.nemo.common.ir.vertex.IRVertex;
 import edu.snu.nemo.common.ir.vertex.LoopVertex;
 import edu.snu.nemo.common.dag.DAG;
 import edu.snu.nemo.common.dag.DAGBuilder;
+import edu.snu.nemo.compiler.optimizer.pass.compiletime.Requires;
 
 import java.util.*;
 import java.util.function.IntPredicate;
@@ -98,12 +99,13 @@ public final class LoopOptimizations {
   /**
    * Pass for Loop Fusion optimization.
    */
+  @Requires(CommunicationPatternProperty.class)
   public static final class LoopFusionPass extends ReshapingPass {
     /**
      * Default constructor.
      */
     public LoopFusionPass() {
-      super(Collections.singleton(CommunicationPatternProperty.class));
+      super(LoopFusionPass.class);
     }
 
     @Override
@@ -246,12 +248,13 @@ public final class LoopOptimizations {
   /**
    * Pass for Loop Invariant Code Motion optimization.
    */
+  @Requires(CommunicationPatternProperty.class)
   public static final class LoopInvariantCodeMotionPass extends ReshapingPass {
     /**
      * Default constructor.
      */
     public LoopInvariantCodeMotionPass() {
-      super(Collections.singleton(CommunicationPatternProperty.class));
+      super(LoopInvariantCodeMotionPass.class);
     }
 
     @Override
diff --git a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/reshaping/LoopUnrollingPass.java b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/reshaping/LoopUnrollingPass.java
index d11b7ab..c1408e5 100644
--- a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/reshaping/LoopUnrollingPass.java
+++ b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/reshaping/LoopUnrollingPass.java
@@ -27,6 +27,13 @@ import edu.snu.nemo.common.ir.vertex.LoopVertex;
  * Then, it decomposes each of the LoopVertices with the DAG information that each of them contain.
  */
 public final class LoopUnrollingPass extends ReshapingPass {
+  /**
+   * Default constructor.
+   */
+  public LoopUnrollingPass() {
+    super(LoopUnrollingPass.class);
+  }
+
   @Override
   public DAG<IRVertex, IREdge> apply(final DAG<IRVertex, IREdge> dag) {
     return recursivelyUnroll(dag);
diff --git a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/reshaping/ReshapingPass.java b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/reshaping/ReshapingPass.java
index d815996..85ec3fd 100644
--- a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/reshaping/ReshapingPass.java
+++ b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/reshaping/ReshapingPass.java
@@ -17,7 +17,9 @@ package edu.snu.nemo.compiler.optimizer.pass.compiletime.reshaping;
 
 import edu.snu.nemo.common.ir.executionproperty.ExecutionProperty;
 import edu.snu.nemo.compiler.optimizer.pass.compiletime.CompileTimePass;
+import edu.snu.nemo.compiler.optimizer.pass.compiletime.Requires;
 
+import java.util.Arrays;
 import java.util.HashSet;
 import java.util.Set;
 
@@ -29,18 +31,13 @@ public abstract class ReshapingPass extends CompileTimePass {
   private final Set<Class<? extends ExecutionProperty>> prerequisiteExecutionProperties;
 
   /**
-   * Default constructor.
-   */
-  public ReshapingPass() {
-    this(new HashSet<>());
-  }
-
-  /**
    * Constructor.
-   * @param prerequisiteExecutionProperties prerequisite of execution properties.
+   * @param cls the reshaping pass class.
    */
-  public ReshapingPass(final Set<Class<? extends ExecutionProperty>> prerequisiteExecutionProperties) {
-    this.prerequisiteExecutionProperties = prerequisiteExecutionProperties;
+  public ReshapingPass(final Class<? extends ReshapingPass> cls) {
+    final Requires requires = cls.getAnnotation(Requires.class);
+    this.prerequisiteExecutionProperties = requires == null
+        ? new HashSet<>() : new HashSet<>(Arrays.asList(requires.value()));
   }
 
   public final Set<Class<? extends ExecutionProperty>> getPrerequisiteExecutionProperties() {
diff --git a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/reshaping/SkewReshapingPass.java b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/reshaping/SkewReshapingPass.java
index f7074bb..a8763bd 100644
--- a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/reshaping/SkewReshapingPass.java
+++ b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/reshaping/SkewReshapingPass.java
@@ -24,9 +24,9 @@ import edu.snu.nemo.common.ir.edge.executionproperty.EncoderProperty;
 import edu.snu.nemo.common.ir.vertex.IRVertex;
 import edu.snu.nemo.common.ir.vertex.MetricCollectionBarrierVertex;
 import edu.snu.nemo.common.ir.vertex.OperatorVertex;
+import edu.snu.nemo.compiler.optimizer.pass.compiletime.Requires;
 
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.List;
 
 /**
@@ -37,12 +37,13 @@ import java.util.List;
  * a snapshot at the end of the pass. This could be prevented by modifying other passes to take the snapshot of the
  * DAG at the end of each passes for metricCollectionVertices.
  */
+@Requires(CommunicationPatternProperty.class)
 public final class SkewReshapingPass extends ReshapingPass {
   /**
    * Default constructor.
    */
   public SkewReshapingPass() {
-    super(Collections.singleton(CommunicationPatternProperty.class));
+    super(SkewReshapingPass.class);
   }
 
   @Override
diff --git a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/policy/PolicyBuilder.java b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/policy/PolicyBuilder.java
index 13a2507..4a84a62 100644
--- a/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/policy/PolicyBuilder.java
+++ b/compiler/optimizer/src/main/java/edu/snu/nemo/compiler/optimizer/policy/PolicyBuilder.java
@@ -81,7 +81,7 @@ public final class PolicyBuilder {
     // check annotation of annotating passes.
     if (compileTimePass instanceof AnnotatingPass) {
       final AnnotatingPass annotatingPass = (AnnotatingPass) compileTimePass;
-      this.annotatedExecutionProperties.add(annotatingPass.getExecutionPropertyToModify());
+      this.annotatedExecutionProperties.addAll(annotatingPass.getExecutionPropertiesToAnnotate());
     }
 
     this.compileTimePasses.add(compileTimePass);
diff --git a/compiler/test/src/test/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/DefaultEdgeCoderPassTest.java b/compiler/test/src/test/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/DefaultEdgeCoderPassTest.java
index e21ee55..800bc40 100644
--- a/compiler/test/src/test/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/DefaultEdgeCoderPassTest.java
+++ b/compiler/test/src/test/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/DefaultEdgeCoderPassTest.java
@@ -31,6 +31,7 @@ import org.powermock.core.classloader.annotations.PrepareForTest;
 import org.powermock.modules.junit4.PowerMockRunner;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
 /**
  * Test {@link DefaultEdgeEncoderPass} and {@link DefaultEdgeDecoderPass}.
@@ -48,9 +49,9 @@ public class DefaultEdgeCoderPassTest {
   @Test
   public void testAnnotatingPass() {
     final AnnotatingPass encoderPass = new DefaultEdgeEncoderPass();
-    assertEquals(EncoderProperty.class, encoderPass.getExecutionPropertyToModify());
+    assertTrue(encoderPass.getExecutionPropertiesToAnnotate().contains(EncoderProperty.class));
     final AnnotatingPass decoderPass = new DefaultEdgeDecoderPass();
-    assertEquals(DecoderProperty.class, decoderPass.getExecutionPropertyToModify());
+    assertTrue(decoderPass.getExecutionPropertiesToAnnotate().contains(DecoderProperty.class));
   }
 
   @Test
diff --git a/compiler/test/src/test/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/DefaultParallelismPassTest.java b/compiler/test/src/test/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/DefaultParallelismPassTest.java
index 59c54c2..1205f64 100644
--- a/compiler/test/src/test/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/DefaultParallelismPassTest.java
+++ b/compiler/test/src/test/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/DefaultParallelismPassTest.java
@@ -29,6 +29,7 @@ import org.powermock.core.classloader.annotations.PrepareForTest;
 import org.powermock.modules.junit4.PowerMockRunner;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
 /**
  * Test {@link DefaultParallelismPass}.
@@ -46,7 +47,7 @@ public class DefaultParallelismPassTest {
   @Test
   public void testAnnotatingPass() {
     final AnnotatingPass parallelismPass = new DefaultParallelismPass();
-    assertEquals(ParallelismProperty.class, parallelismPass.getExecutionPropertyToModify());
+    assertTrue(parallelismPass.getExecutionPropertiesToAnnotate().contains(ParallelismProperty.class));
   }
 
   @Test
diff --git a/compiler/test/src/test/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/DefaultScheduleGroupPassTest.java b/compiler/test/src/test/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/DefaultScheduleGroupPassTest.java
index 70b3275..c8bfc85 100644
--- a/compiler/test/src/test/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/DefaultScheduleGroupPassTest.java
+++ b/compiler/test/src/test/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/annotating/DefaultScheduleGroupPassTest.java
@@ -48,7 +48,7 @@ public final class DefaultScheduleGroupPassTest {
   @Test
   public void testAnnotatingPass() {
     final AnnotatingPass scheduleGroupPass = new DefaultScheduleGroupPass();
-    assertEquals(ScheduleGroupProperty.class, scheduleGroupPass.getExecutionPropertyToModify());
+    assertTrue(scheduleGroupPass.getExecutionPropertiesToAnnotate().contains(ScheduleGroupProperty.class));
   }
 
   /**
diff --git a/compiler/test/src/test/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/composite/SkewCompositePassTest.java b/compiler/test/src/test/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/composite/SkewCompositePassTest.java
index ed21561..1cd8996 100644
--- a/compiler/test/src/test/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/composite/SkewCompositePassTest.java
+++ b/compiler/test/src/test/java/edu/snu/nemo/compiler/optimizer/pass/compiletime/composite/SkewCompositePassTest.java
@@ -67,7 +67,7 @@ public class SkewCompositePassTest {
         prerequisites.addAll(compileTimePass.getPrerequisiteExecutionProperties()));
     dataSkewPass.getPassList().forEach(compileTimePass -> {
       if (compileTimePass instanceof AnnotatingPass) {
-        prerequisites.remove(((AnnotatingPass) compileTimePass).getExecutionPropertyToModify());
+        prerequisites.removeAll(((AnnotatingPass) compileTimePass).getExecutionPropertiesToAnnotate());
       }
     });
     assertEquals(prerequisites, dataSkewPass.getPrerequisiteExecutionProperties());