public StrengthReduction(SsaState ssa, LinearInductionVariable liv, LinearInductionVariableContext ctx)
 {
     this.ssa = ssa;
     this.liv = liv;
     this.ctx = ctx;
     incrUses = new List<IncrementedUse>();
 }
		public static LinearInductionVariable Merge(LinearInductionVariable liv1, LinearInductionVariable liv2)
		{
			if (liv1.Delta == null || liv2.Delta == null)
				return null;
			int delta1 = Convert.ToInt32(liv1.Delta.ToInt32());
			int delta2 = Convert.ToInt32(liv2.Delta.ToInt32());
			if (delta1 == 1)
				return new LinearInductionVariable(null, liv1.Delta, null, liv1.IsSigned);
			else if (delta2 == 1)
				return new LinearInductionVariable(null, liv2.Delta, null, liv2.IsSigned);
			else
			{
				int delta = Gcd(delta1, delta2);
				if (delta == 1)
					return null;
				else
					return new LinearInductionVariable(null, Constant.Create(liv1.Delta.DataType, delta),
                        null, liv1.IsSigned || liv2.IsSigned);
			}
		}
        public void DtbInductionVariables()
        {
            Identifier i = new Identifier("i", PrimitiveType.Word32, null);
            MemoryAccess load = new MemoryAccess(MemoryIdentifier.GlobalMemory, i, PrimitiveType.Int32);
            Identifier i2 = new Identifier("i2", PrimitiveType.Word32, null);
            MemoryAccess ld2 = new MemoryAccess(MemoryIdentifier.GlobalMemory, i2, PrimitiveType.Int32);

            LinearInductionVariable iv = new LinearInductionVariable(
                Constant.Word32(0),
                Constant.Word32(1),
                Constant.Word32(10),
                false);
            LinearInductionVariable iv2 = new LinearInductionVariable(
                Constant.Word32(0x0010000),
                Constant.Word32(4),
                Constant.Word32(0x0010040),
                false);

            prog.InductionVariables.Add(i, iv);
            prog.InductionVariables.Add(i2, iv2);
            prog.Platform = new DefaultPlatform(null, arch);
            TraitCollector trco = new TraitCollector(factory, store, dtb, prog);

            prog.Globals.Accept(eqb);
            load.Accept(eqb);
            ld2.Accept(eqb);
            prog.Globals.Accept(trco);
            load.Accept(trco);
            ld2.Accept(trco);
            dtb.BuildEquivalenceClassDataTypes();

            Verify("Typing/DtbInductionVariables.txt");
        }
        /// <summary>
        /// Handle an expression of type 'id + offset', where id is a LinearInductionVariable.
        /// </summary>
        /// <param name="id"></param>
        /// <param name="iv"></param>
        /// <param name="offset"></param>
		public void VisitInductionVariable(Identifier id, LinearInductionVariable iv, Constant cOffset)
		{
            int delta = iv.Delta.ToInt32();
            int offset = StructureField.ToOffset(cOffset);
            var tvBase = (basePointer != null) ? basePointer : prog.Globals;
            var stride = Math.Abs(delta);
            int init;
            if (delta < 0)
            {
                // induction variable is decremented, so the actual array begins at ivFinal - delta.
                if (iv.Final != null)
                {
                    init = iv.Final.ToInt32() - delta;
                    if (iv.IsSigned)
                    {
                        handler.MemAccessArrayTrait(null, tvBase, cOffset.DataType.Size, init + offset, stride, iv.IterationCount, eField);
                    }
                    else
                    {
                        handler.MemAccessArrayTrait(null, tvBase, id.DataType.Size, init + offset, stride, iv.IterationCount, eField);
                    }
                }
            }
            else
            {
                if (iv.Initial != null)
                {
                    init = iv.Initial.ToInt32();
                    if (iv.IsSigned)
                    {
                        handler.MemAccessArrayTrait(null, tvBase, cOffset.DataType.Size, init + offset, stride, iv.IterationCount, eField);
                    }
                    else
                    {
                        handler.MemAccessArrayTrait(null, tvBase, id.DataType.Size, init + offset, stride, iv.IterationCount, eField);
                    }
                }
            }
            if (iv.IsSigned)
            {
                if (cOffset != null)
                {
                    handler.MemSizeTrait(basePointer, cOffset, Math.Abs(delta));
                    EmitAccessTrait(basePointer, cOffset, cOffset.DataType.Size, 0);
                }
            }
            else
            {
                handler.MemSizeTrait(basePointer, id, Math.Abs(delta));
                EmitAccessTrait(basePointer, id, id.DataType.Size, offset);
            }
		}
		public void InCommensurate()
		{
			LinearInductionVariable liv1 = new LinearInductionVariable(null, Constant.Word32(3), null, false);
			LinearInductionVariable liv2 = new LinearInductionVariable(null, Constant.Word32(8), null, false);
			LinearInductionVariable liv =
				LinearInductionVariable.Merge(liv1, liv2);
			Assert.IsNull(liv);
		}
		public void Commensurate2()
		{
            LinearInductionVariable liv1 = new LinearInductionVariable(null, Constant.Word32(2), null, false);
            LinearInductionVariable liv2 = new LinearInductionVariable(null, Constant.Word32(8), null, false);
			LinearInductionVariable liv =
				LinearInductionVariable.Merge(liv1, liv2);
			Assert.IsNotNull(liv);
			Assert.AreEqual(2, liv.Delta.ToInt32());
		}
		public void TrcoInductionVariable()
		{
			Identifier i = new Identifier("i", PrimitiveType.Word32, null);
			MemoryAccess load = new MemoryAccess(MemoryIdentifier.GlobalMemory, i, PrimitiveType.Int32);
			Identifier i2 = new Identifier("i2", PrimitiveType.Word32, null);
			MemoryAccess ld2 = new MemoryAccess(MemoryIdentifier.GlobalMemory, i2, PrimitiveType.Int32);

			LinearInductionVariable iv = new LinearInductionVariable(
				Constant.Word32(0), 
				Constant.Word32(1),
				Constant.Word32(10),
                false);
			LinearInductionVariable iv2 = new LinearInductionVariable(
				Constant.Word32(0x0010000),
				Constant.Word32(4),
				Constant.Word32(0x0010040),
                false);

            Program prog = CreateProgram();
			prog.InductionVariables.Add(i, iv);
			prog.InductionVariables.Add(i2, iv2);

            coll = CreateCollector(prog);
			prog.Globals.Accept(eqb);
			load.Accept(eqb);
			ld2.Accept(eqb);
			prog.Globals.Accept(coll);
			load.Accept(coll);
			ld2.Accept(coll);
			Verify(null, "Typing/TrcoInductionVariable.txt");
		}