Ejemplo n.º 1
0
        private static BasicBlock InlineIR(this IList <BasicBlockInstruction> code,
                                           ControlFlowInstruction trailer,
                                           Func <Subprogram, bool> permitInline,
                                           Dictionary <VirtualRegister, VirtualRegister> copyRegMap,
                                           Dictionary <Subprogram, Dictionary <VirtualRegister, VirtualRegister> > inlineRegMaps,
                                           IList <Subprogram> subprograms,
                                           out BasicBlock backend)
        {
            List <BasicBlockInstruction> preamble = new List <BasicBlockInstruction>();
            int i = 0;

            while (i < code.Count && !(code[i].OpCode == IROpCodes.CALL &&
                                       permitInline(subprograms.Single(sp => sp.Name == (code[i] as CALLInstruction).Target.Name))))
            {
                preamble.Add(code[i++].MapInstruction(copyRegMap));
            }
            if (i < code.Count)
            {
                CALLInstruction call = code[i++] as CALLInstruction;
                call = new CALLInstruction(subprograms.Single(sp => sp.Name == call.Target.Name),
                                           call.Arguments.Select(op => op.MapOperand(copyRegMap)).ToList());

                List <BasicBlockInstruction> tail = new List <BasicBlockInstruction>();
                while (i < code.Count)
                {
                    tail.Add(code[i++]);
                }

                return(call.InlineIR(preamble, tail.InlineIR(trailer, permitInline, copyRegMap,
                                                             inlineRegMaps, subprograms, out backend), inlineRegMaps));
            }
            else
            {
                backend = new BasicBlock(preamble, trailer);
                return(backend);
            }
        }
Ejemplo n.º 2
0
		private static BasicBlock InlineIR(this IList<BasicBlockInstruction> code,
			ControlFlowInstruction trailer,
			Func<Subprogram, bool> permitInline,
			Dictionary<VirtualRegister, VirtualRegister> copyRegMap,
			Dictionary<Subprogram, Dictionary<VirtualRegister, VirtualRegister>> inlineRegMaps,
			IList<Subprogram> subprograms,
			out BasicBlock backend)
		{
			List<BasicBlockInstruction> preamble = new List<BasicBlockInstruction>();
			int i = 0;
			while (i < code.Count && !(code[i].OpCode == IROpCodes.CALL &&
				permitInline(subprograms.Single(sp => sp.Name == (code[i] as CALLInstruction).Target.Name))))
				preamble.Add(code[i++].MapInstruction(copyRegMap));
			if (i < code.Count)
			{
				CALLInstruction call = code[i++] as CALLInstruction;
				call = new CALLInstruction(subprograms.Single(sp => sp.Name == call.Target.Name),
					call.Arguments.Select(op => op.MapOperand(copyRegMap)).ToList());
				
				List<BasicBlockInstruction> tail = new List<BasicBlockInstruction>();
				while (i < code.Count)
					tail.Add(code[i++]);					
				
				return call.InlineIR(preamble, tail.InlineIR(trailer, permitInline, copyRegMap, 
					inlineRegMaps, subprograms, out backend), inlineRegMaps);
			}
			else
			{
				backend = new BasicBlock(preamble, trailer);
				return backend;
			}
		}
Ejemplo n.º 3
0
        public static BasicBlockInstruction MapInstruction(this BasicBlockInstruction bbi,
                                                           Dictionary <VirtualRegister, VirtualRegister> regmap)
        {
            switch (bbi.OpCode)
            {
            case IROpCodes.ADD:
            case IROpCodes.SUB:
            case IROpCodes.MUL:
            case IROpCodes.DIV:
            case IROpCodes.MIN:
            case IROpCodes.MAX:
            case IROpCodes.REM:
            case IROpCodes.AND:
            case IROpCodes.OR:
            case IROpCodes.XOR:
            case IROpCodes.EQ:
            case IROpCodes.NE:
            case IROpCodes.GE:
            case IROpCodes.GT:
            case IROpCodes.LE:
            case IROpCodes.LT:
                BinaryOperation bop = bbi as BinaryOperation;
                return(new BinaryOperation(bop.OpCode, bop.Target.MapOperand(regmap),
                                           bop.LeftOperand.MapOperand(regmap), bop.RightOperand.MapOperand(regmap)));

            case IROpCodes.MAD:
                MADOperation mad = bbi as MADOperation;
                return(new MADOperation(mad.Target.MapOperand(regmap),
                                        mad.MulLeftOperand.MapOperand(regmap), mad.MulRightOperand.MapOperand(regmap),
                                        mad.AddOperand.MapOperand(regmap)));

            case IROpCodes.NEG:
            case IROpCodes.ABS:
            case IROpCodes.NOT:
            case IROpCodes.SQRT:
            case IROpCodes.RSQRT:
            case IROpCodes.SIN:
            case IROpCodes.COS:
            case IROpCodes.LG2:
            case IROpCodes.EX2:
            case IROpCodes.MOV:
            case IROpCodes.CVT:
                UnaryOperation uop = bbi as UnaryOperation;
                return(new UnaryOperation(uop.OpCode, uop.Target.MapOperand(regmap), uop.Operand.MapOperand(regmap)));

            case IROpCodes.LD:
                LDInstruction load = bbi as LDInstruction;
                return(new LDInstruction(load.Target.MapOperand(regmap), load.Address.MapOperand(regmap)));

            case IROpCodes.ST:
                STInstruction store = bbi as STInstruction;
                return(new STInstruction(store.Address.MapOperand(regmap), store.Source.MapOperand(regmap)));

            case IROpCodes.CALL:
                CALLInstruction call = bbi as CALLInstruction;
                return(new CALLInstruction(call.Target, call.Arguments.Select(op => op.MapOperand(regmap)).ToList()));

            case IROpCodes.SYNC:
                return(new SYNCInstruction());

            default:
                throw new NotSupportedException();
            }
        }
Ejemplo n.º 4
0
        private static BasicBlock InlineIR(this CALLInstruction call,
                                           IList <BasicBlockInstruction> preamble,
                                           BasicBlock backend,
                                           Dictionary <Subprogram, Dictionary <VirtualRegister, VirtualRegister> > inlineRegMaps)
        {
            Dictionary <VirtualRegister, VirtualRegister> inlineRegMap;

            if (!inlineRegMaps.TryGetValue(call.Target, out inlineRegMap))
            {
                inlineRegMap = call.Target.LocalVariables.Select(lv =>
                                                                 new KeyValuePair <VirtualRegister, VirtualRegister>(lv, new VirtualRegister(lv.UnderlyingType, lv.StateSpace))).
                               ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
                inlineRegMaps.Add(call.Target, inlineRegMap);
            }
            inlineRegMap = inlineRegMap.Concat(call.Target.FormalParameters.Zip(call.Arguments,
                                                                                (formal, actual) => new KeyValuePair <VirtualRegister, VirtualRegister>(formal,
                                                                                                                                                        (actual is VirtualRegister) ? (actual as VirtualRegister) :
                                                                                                                                                        (formal.StateSpace != StateSpaces.REG) ? new VirtualRegister(formal.UnderlyingType, formal.StateSpace) :
                                                                                                                                                        new VirtualRegister(formal.DataType)))).
                           ToDictionary(kvp => kvp.Key, kvp => kvp.Value);

            Dictionary <BasicBlock, BasicBlock> cfgmap = call.Target.GetBasicBlocks().Select(bb =>
            {
                VirtualRegister flag = (bb.Trailer is JumpIfInstruction) ?
                                       (bb.Trailer as JumpIfInstruction).Flag.MapOperand(inlineRegMap) : null;

                ControlFlowInstruction trailer;

                switch (bb.Trailer.OpCode)
                {
                case IROpCodes.RET:
                    trailer = new JMPInstruction()
                    {
                        Target = backend
                    };
                    break;

                case IROpCodes.JMP:
                    trailer = new JMPInstruction();
                    break;

                case IROpCodes.JT:
                    trailer = new JTInstruction(flag);
                    break;

                case IROpCodes.JF:
                    trailer = new JFInstruction(flag);
                    break;

                default:
                    throw new NotSupportedException();
                }

                return(new KeyValuePair <BasicBlock, BasicBlock>(bb,
                                                                 new BasicBlock(bb.Code.Select(bbi => bbi.MapInstruction(inlineRegMap)).ToList(), trailer)));
            }).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);

            foreach (KeyValuePair <BasicBlock, BasicBlock> bbmap in cfgmap)
            {
                if (bbmap.Key.Successor != null)
                {
                    bbmap.Value.Successor = cfgmap[bbmap.Key.Successor];
                }
                if (bbmap.Key.Target != null)
                {
                    bbmap.Value.Target = cfgmap[bbmap.Key.Target];
                }
            }

            BasicBlock root = cfgmap[call.Target.CFGRoot];

            return(new BasicBlock(preamble.Concat(root.Code).ToList(), root.Trailer));
        }