public HighPhi(HighSsaRegister dest, HighPhiLink[] links) { if (dest.IsConstant) throw new ArgumentException("Can't use a constant as a phi destination"); m_dest = dest; m_links = links; }
private CppTranslatedOutboundEdge InternOutboundEdge(CfgNode node, CfgOutboundEdge edge) { CppTranslatedOutboundEdge outboundEdge; if (m_translatedOutboundEdges.TryGetValue(edge, out outboundEdge)) return outboundEdge; bool needRegTranslation = false; int survivingRegsCount = edge.SurvivingRegs.Length; CfgNode successorNode = edge.SuccessorNode; for (int i = 0; i < survivingRegsCount; i++) { CLR.CLRTypeSpec outType = edge.SurvivingRegs[i].VType.TypeSpec; CLR.CLRTypeSpec inType = successorNode.EntryTypes[i].TypeSpec; if (!outType.Equals(inType)) { needRegTranslation = true; break; } } Clarity.Rpa.HighCfgNodeHandle prevNode = InternHighCfgNode(node); if (!needRegTranslation) { List<Clarity.Rpa.HighSsaRegister> regs = new List<Clarity.Rpa.HighSsaRegister>(); foreach (SsaRegister reg in edge.SurvivingRegs) regs.Add(InternSsaRegister(reg)); Clarity.Rpa.HighCfgNodeHandle nextNode = InternHighCfgNode(edge.SuccessorNode); outboundEdge = new CppTranslatedOutboundEdge(prevNode, nextNode, regs); } else { List<Clarity.Rpa.HighInstruction> instrs = new List<Clarity.Rpa.HighInstruction>(); List<Clarity.Rpa.HighSsaRegister> regs = new List<Clarity.Rpa.HighSsaRegister>(); List<Clarity.Rpa.HighPhi> phis = new List<Clarity.Rpa.HighPhi>(); Clarity.Rpa.HighCfgNodeHandle nextNode = InternHighCfgNode(edge.SuccessorNode); MidInstruction[] midInstrs = edge.SuccessorNode.MidInstructions; for (int i = 0; i < survivingRegsCount; i++) { MidInstruction midInstr = midInstrs[i]; if (midInstr.Opcode != MidInstruction.OpcodeEnum.EntryReg) throw new Exception("Internal error"); Clarity.Rpa.HighSsaRegister sourceReg = InternSsaRegister(edge.SurvivingRegs[i]); Clarity.Rpa.HighSsaRegister targetReg = InternSsaRegister(midInstr.RegArg); if (!targetReg.IsConstant) { HighSsaRegister importReg = new HighSsaRegister(sourceReg.ValueType, sourceReg.Type, sourceReg.ConstantValue); HighSsaRegister exportReg = new HighSsaRegister(targetReg.ValueType, targetReg.Type, targetReg.ConstantValue); HighPhiLink phiLink = new HighPhiLink(prevNode, sourceReg); phis.Add(new HighPhi(importReg, new HighPhiLink[] { phiLink })); instrs.Add(new Clarity.Rpa.Instructions.PassiveConvertInstruction( midInstr.CodeLocation, exportReg, importReg )); regs.Add(exportReg); } else regs.Add(targetReg); } instrs.Add(new Clarity.Rpa.Instructions.BranchInstruction(edge.CodeLocation, nextNode)); Clarity.Rpa.HighCfgNode cfgNode = new HighCfgNode(new Clarity.Rpa.HighCfgNodeHandle[] { prevNode }, phis.ToArray(), instrs.ToArray()); Clarity.Rpa.HighCfgNodeHandle cfgNodeHandle = new Clarity.Rpa.HighCfgNodeHandle(cfgNode); outboundEdge = new CppTranslatedOutboundEdge(cfgNodeHandle, cfgNodeHandle, regs); } m_translatedOutboundEdges.Add(edge, outboundEdge); return outboundEdge; }
public override RloMethod GenerateMethod(Compiler compiler, MethodInstantiationPath instantiationPath) { TypeSpecClassTag delegateClassType = m_dt; CliClass delegateCls = compiler.GetClosedClass(delegateClassType); TypeNameTag delegateTypeName = delegateCls.TypeName; HighTypeDef delegateTypeDef = compiler.GetTypeDef(delegateTypeName); if (delegateTypeDef.Semantics != TypeSemantics.Delegate) throw new RpaCompileException("Delegate-bound class is not a delegate"); MethodSignatureTag declSignature = delegateTypeDef.DelegateSignature; MethodDeclTag invokeDeclTag = new MethodDeclTag("Invoke", declSignature, delegateTypeName); invokeDeclTag = compiler.TagRepository.InternMethodDeclTag(invokeDeclTag); uint vtableSlotIndex = delegateCls.DeclTagToVTableSlot[invokeDeclTag]; CliVtableSlot vtableSlot = delegateCls.VTable[vtableSlotIndex]; MethodSignatureTag delegateMethodSignature = vtableSlot.MethodSignature; TypeSpecMulticastDelegateTag mdType = new TypeSpecMulticastDelegateTag(m_dt); mdType = (TypeSpecMulticastDelegateTag)compiler.TagRepository.InternTypeSpec(mdType); List<HighSsaRegister> loadedParams = new List<HighSsaRegister>(); HighLocal thisLocal = new HighLocal(mdType, HighLocal.ETypeOfType.Value); List<HighLocal> args = new List<HighLocal>(); HighSsaRegister thisReg = new HighSsaRegister(HighValueType.ReferenceValue, mdType, null); List<HighInstruction> entryInstrs = new List<HighInstruction>(); entryInstrs.Add(new Rpa.Instructions.LoadLocalInstruction(null, thisReg, thisLocal)); foreach (MethodSignatureParam param in delegateMethodSignature.ParamTypes) { switch (param.TypeOfType.Value) { case MethodSignatureParamTypeOfType.Values.ByRef: { HighSsaRegister paramSsa = new HighSsaRegister(HighValueType.ManagedPtr, param.Type, null); HighLocal local = new HighLocal(param.Type, HighLocal.ETypeOfType.ByRef); args.Add(local); entryInstrs.Add(new Rpa.Instructions.LoadLocalInstruction(null, paramSsa, local)); loadedParams.Add(paramSsa); } break; case MethodSignatureParamTypeOfType.Values.Value: { bool isValueType = compiler.TypeIsValueType(param.Type); HighSsaRegister paramSsa = new HighSsaRegister(isValueType ? HighValueType.ValueValue : HighValueType.ReferenceValue, param.Type, null); HighLocal local = new HighLocal(param.Type, HighLocal.ETypeOfType.Value); args.Add(local); entryInstrs.Add(new Rpa.Instructions.LoadLocalInstruction(null, paramSsa, local)); loadedParams.Add(paramSsa); } break; case MethodSignatureParamTypeOfType.Values.TypedByRef: throw new NotImplementedException(); default: throw new Exception(); } } HighSsaRegister returnValue = null; if (!(delegateMethodSignature.RetType is TypeSpecVoidTag)) { bool isValueType = compiler.TypeIsValueType(delegateMethodSignature.RetType); returnValue = new HighSsaRegister(isValueType ? HighValueType.ValueValue : HighValueType.ReferenceValue, delegateMethodSignature.RetType, null); } TypeSpecClassTag nativeUIntType = m_vtCache.GetSystemUIntPtrType(compiler); HighSsaRegister numDelegatesValue = new HighSsaRegister(HighValueType.ValueValue, nativeUIntType, null); HighSsaRegister zeroNativeUIntConstant = new HighSsaRegister(HighValueType.ConstantValue, nativeUIntType, (ulong)0); HighCfgNodeHandle entryHdl = new HighCfgNodeHandle(); HighCfgNodeHandle loopCallHdl = new HighCfgNodeHandle(); HighCfgNodeHandle loopIncrementHdl = new HighCfgNodeHandle(); HighCfgNodeHandle returnHdl = new HighCfgNodeHandle(); HighSsaRegister postIncrementReg = new HighSsaRegister(HighValueType.ValueValue, nativeUIntType, null); entryInstrs.Add(new Instructions.GetMulticastDelegateInvocationCountInstruction(null, numDelegatesValue, thisReg)); entryInstrs.Add(new Rpa.Instructions.BranchInstruction(null, loopCallHdl)); entryHdl.Value = new HighCfgNode(entryInstrs.ToArray()); HighSsaRegister currentCountReg = new HighSsaRegister(HighValueType.ValueValue, nativeUIntType, null); { List<HighInstruction> instrs = new List<HighInstruction>(); HighSsaRegister delegateValue = new HighSsaRegister(HighValueType.ReferenceValue, m_dt, null); HighInstruction callInstr = new Instructions.CallRloVirtualMethodInstruction(null, vtableSlotIndex, returnValue, thisReg, loadedParams.ToArray()); callInstr.ContinuationEdge = new HighCfgEdge(callInstr, loopIncrementHdl); instrs.Add(callInstr); HighPhiLink[] loopLinks = new HighPhiLink[] { new HighPhiLink(entryHdl, zeroNativeUIntConstant), new HighPhiLink(loopIncrementHdl, postIncrementReg) }; HighCfgNodeHandle[] loopPredecessors = new HighCfgNodeHandle[] { entryHdl, loopIncrementHdl, }; HighPhi phi = new HighPhi(currentCountReg, loopLinks); loopCallHdl.Value = new HighCfgNode(loopPredecessors, new HighPhi[] { phi }, instrs.ToArray()); } { List<HighInstruction> instrs = new List<HighInstruction>(); HighSsaRegister oneConstant = new HighSsaRegister(HighValueType.ConstantValue, nativeUIntType, (ulong)1); instrs.Add(new Rpa.Instructions.ArithInstruction(null, postIncrementReg, Rpa.Instructions.NumberArithOp.Add, Rpa.Instructions.NumberArithType.NativeUInt, currentCountReg, oneConstant, false)); instrs.Add(new Rpa.Instructions.BranchCompareNumbersInstruction(null, Rpa.Instructions.NumberCompareOperation.LessThan, Rpa.Instructions.NumberArithType.NativeUInt, currentCountReg, numDelegatesValue, loopCallHdl, returnHdl)); loopIncrementHdl.Value = new HighCfgNode(instrs.ToArray()); } { List<HighInstruction> instrs = new List<HighInstruction>(); if (returnValue == null) instrs.Add(new Rpa.Instructions.ReturnInstruction(null)); else instrs.Add(new Rpa.Instructions.ReturnValueInstruction(null, returnValue)); returnHdl.Value = new HighCfgNode(instrs.ToArray()); } HighRegion region = new HighRegion(entryHdl); RloMethodBody methodBody = new RloMethodBody(thisLocal, args.ToArray(), new HighLocal[0], delegateMethodSignature.RetType, region, delegateMethodSignature, instantiationPath); return new RloMethod(methodBody); }