001/*
002 * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation.
008 *
009 * This code is distributed in the hope that it will be useful, but WITHOUT
010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
011 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
012 * version 2 for more details (a copy is included in the LICENSE file that
013 * accompanied this code).
014 *
015 * You should have received a copy of the GNU General Public License version
016 * 2 along with this work; if not, write to the Free Software Foundation,
017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
018 *
019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
020 * or visit www.oracle.com if you need additional information or have any
021 * questions.
022 */
023package com.oracle.graal.loop;
024
025import jdk.internal.jvmci.common.*;
026
027import com.oracle.graal.compiler.common.type.*;
028import com.oracle.graal.nodes.*;
029
030/**
031 * This class describes a value node that is an induction variable in a counted loop.
032 */
033public abstract class InductionVariable {
034
035    public enum Direction {
036        Up,
037        Down;
038
039        public Direction opposite() {
040            switch (this) {
041                case Up:
042                    return Down;
043                case Down:
044                    return Up;
045                default:
046                    throw JVMCIError.shouldNotReachHere();
047            }
048        }
049    }
050
051    public abstract StructuredGraph graph();
052
053    protected final LoopEx loop;
054
055    public InductionVariable(LoopEx loop) {
056        this.loop = loop;
057    }
058
059    public LoopEx getLoop() {
060        return loop;
061    }
062
063    public abstract Direction direction();
064
065    /**
066     * Returns the value node that is described by this induction variable.
067     */
068    public abstract ValueNode valueNode();
069
070    /**
071     * Returns the node that gives the initial value of this induction variable.
072     */
073    public abstract ValueNode initNode();
074
075    /**
076     * Returns the stride of the induction variable. The stride is the value that is added to the
077     * induction variable at each iteration.
078     */
079    public abstract ValueNode strideNode();
080
081    public abstract boolean isConstantInit();
082
083    public abstract boolean isConstantStride();
084
085    public abstract long constantInit();
086
087    public abstract long constantStride();
088
089    /**
090     * Returns the extremum value of the induction variable. The extremum value is the value of the
091     * induction variable in the loop body of the last iteration, only taking into account the main
092     * loop limit test. It's possible for the loop to exit before this value if
093     * {@link CountedLoopInfo#isExactTripCount()} returns false for the containing loop.
094     */
095    public ValueNode extremumNode() {
096        return extremumNode(false, valueNode().stamp());
097    }
098
099    public abstract ValueNode extremumNode(boolean assumePositiveTripCount, Stamp stamp);
100
101    public abstract boolean isConstantExtremum();
102
103    public abstract long constantExtremum();
104
105    /**
106     * Returns the exit value of the induction variable. The exit value is the value of the
107     * induction variable at the loop exit.
108     */
109    public abstract ValueNode exitValueNode();
110
111    /**
112     * Deletes any nodes created within the scope of this object that have no usages.
113     */
114    public abstract void deleteUnusedNodes();
115}