Skip to content

Commit 413b4ff

Browse files
committed
Refactor PDU detection and optimize function handling
Focused on improving PDU handling, optimizing analysis, and generating necessary functions.
1 parent 8b49c07 commit 413b4ff

File tree

6 files changed

+114
-39
lines changed

6 files changed

+114
-39
lines changed

BackendAst/DAstConstruction.fs

Lines changed: 92 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1000,42 +1000,78 @@ let private mapFile (r:Asn1AcnAst.AstRoot) (newTasMap : Map<TypeAssignmentInfo,
10001000
let private reMapFile (r:Asn1AcnAst.AstRoot) (icdStgFileName:string) (files0:Asn1File list) (deps:Asn1AcnAst.AcnInsertedFieldDependencies) (lm:LanguageMacros) (f:Asn1File) (us:State) =
10011001
let newModules, ns = f.Modules |> foldMap (fun cs m -> reMapModule r icdStgFileName files0 deps lm m cs) us
10021002
{f with Modules = newModules}, ns
1003-
(*
1004-
//the following functions determines which functions are used by PDU types.
1005-
//Only those functions are generated in the generated code.
1006-
let determinGeneratedFunctions (r:Asn1AcnAst.AstRoot) (files: Asn1File list) (us:State) =
1007-
let getFunctionCalls (tasId:ReferenceToType)=
1003+
1004+
let detectPDUs (r:Asn1AcnAst.AstRoot) (us:State) =
1005+
let functionTypes = Set.ofList [AcnEncDecFunctionType]
1006+
let functionCalls = us.functionCalls |> Map.filter(fun z _ -> z.funcType = AcnEncDecFunctionType)
1007+
printfn "Detecting PDUs. Function calls: %d" functionCalls.Count
1008+
1009+
let memo = System.Collections.Generic.Dictionary<Caller, Set<Caller> >()
1010+
let rec getCallees2 bIsTass (c: Caller) =
1011+
let getCallees2_aux (c: Caller) =
1012+
if memo.ContainsKey(c) then
1013+
memo.[c]
1014+
else
1015+
let result =
1016+
match functionCalls.ContainsKey(c) with
1017+
| false ->
1018+
match bIsTass with
1019+
| true -> Set.empty
1020+
| false -> Set.singleton c
1021+
| true ->
1022+
let callees = functionCalls.[c]
1023+
let ret2 =
1024+
callees
1025+
|> List.map (fun callee -> getCallees2 false {Caller.typeId = callee.typeId; funcType = callee.funcType})
1026+
|> List.fold Set.union Set.empty
1027+
match bIsTass with
1028+
| true -> ret2
1029+
| false -> Set.add c ret2
1030+
memo.[c] <- result
1031+
result
1032+
getCallees2_aux c
1033+
1034+
let callesList =
10081035
seq {
1009-
for c in us.functionCalls do
1010-
if c.Key.typeId.AsString.StartsWith (tasId.AsString) then
1011-
yield (c.Key, c.Value)
1036+
for f in r.Files do
1037+
for m in f.Modules do
1038+
for tas in m.TypeAssignments do
1039+
for fncType in functionTypes do
1040+
//let msg = sprintf "Processing %s.%s. " m.Name.Value tas.Name.Value
1041+
//printf "%s" msg
1042+
let tsInfo = {TypeAssignmentInfo.modName = m.Name.Value; tasName = tas.Name.Value}
1043+
let caller = {Caller.typeId = tsInfo; funcType = fncType}
1044+
//let calles = getCallees true caller |> List.map(fun c -> c.typeId) |> List.distinct
1045+
let calles = getCallees2 true caller |> Set.map(fun c -> c.typeId)
1046+
//printfn "Calles detected: %d" calles.Length
1047+
yield calles
10121048
} |> Seq.toList
1049+
printfn "Calles detected: %d" callesList.Length
1050+
//let callesMap = callesList |> List.collect id |> List.distinct |> Set.ofList
1051+
let callesMap = callesList |> List.fold (fun acc x -> Set.union acc x) Set.empty
10131052

1014-
let allTasses =
1053+
//PDUS are the types that are not called by any other types
1054+
let pdus =
10151055
seq {
1016-
for f in files do
1056+
for f in r.Files do
10171057
for m in f.Modules do
10181058
for tas in m.TypeAssignments do
1019-
match tas.Type.isValidFunction with
1020-
| None -> ()
1021-
| Some isValidFunction ->
1022-
match isValidFunction.funcName with
1023-
| None -> ()
1024-
| Some fncName ->
1025-
let fncCalls = getFunctionCalls tas.Type.id
1026-
yield {modName = m.Name.Value; tasName = tas.Name.Value; validationFunName = fncName; validationDependencies = fncCalls}
1027-
1028-
} |> List.ofSeq
1029-
let ret =
1030-
match r.args.icdPdus with
1031-
| None -> allTasses |> List.map(fun tas -> tas.modName, tas.tasName)
1032-
| Some pdus ->
1033-
let pduTas = pdus |> List.choose (fun pdu -> allTasses |> List.tryFind(fun tas -> tas.tasName = pdu))
1034-
0
1035-
0
1036-
1037-
*)
1038-
1059+
let tsInfo = {TypeAssignmentInfo.modName = m.Name.Value; tasName = tas.Name.Value}
1060+
if not (callesMap.Contains tsInfo) then
1061+
//printfn "PDU detected: %s.%s" m.Name.Value tas.Name.Value
1062+
let caller = {Caller.typeId = tsInfo; funcType = AcnEncDecFunctionType}
1063+
//let calles = getCallees true caller |> List.map(fun c -> c.typeId) |> List.distinct
1064+
let calles = getCallees2 true caller |> Set.map(fun c -> c.typeId)
1065+
if (calles.Count > 0) then
1066+
printfn "PDU %s.%s detected. It has %d callees" m.Name.Value tas.Name.Value calles.Count
1067+
yield (tsInfo, calles)
1068+
} |> Seq.toList
1069+
1070+
let pudsSorted = pdus |> List.sortByDescending(fun (tas, calles) -> calles.Count)
1071+
let maxToPrint = min 5 (pudsSorted.Length)
1072+
printfn "PDUs detected: %d. Printing the first %d" pudsSorted.Length maxToPrint
1073+
for (tas, calles) in pudsSorted |> List.take maxToPrint do
1074+
printfn "%s.%s references %d types" tas.modName tas.tasName calles.Count
10391075

10401076
let calculateFunctionToBeGenerated (r:Asn1AcnAst.AstRoot) (us:State) =
10411077
let functionCalls = us.functionCalls
@@ -1051,6 +1087,7 @@ let calculateFunctionToBeGenerated (r:Asn1AcnAst.AstRoot) (us:State) =
10511087
if requiresAcn then yield AcnEncDecFunctionType;
10521088
} |> Seq.toList
10531089

1090+
(*
10541091
let rec getCallees (c: Caller)=
10551092
seq {
10561093
yield c
@@ -1061,6 +1098,27 @@ let calculateFunctionToBeGenerated (r:Asn1AcnAst.AstRoot) (us:State) =
10611098
for callee in callees do
10621099
yield! getCallees {Caller.typeId = callee.typeId; funcType = callee.funcType}
10631100
} |> Seq.toList
1101+
*)
1102+
let memo2 = System.Collections.Generic.Dictionary<Caller, Set<Caller> >()
1103+
let rec getCallees (c: Caller)=
1104+
if memo2.Count%50 = 0 then printfn "Processing %d" memo2.Count
1105+
match memo2.ContainsKey(c) with
1106+
| true -> memo2.[c]
1107+
| false ->
1108+
let getCallees_aux (c: Caller) =
1109+
let result =
1110+
match functionCalls.ContainsKey c with
1111+
| false -> Set.singleton c
1112+
| true ->
1113+
let callees = functionCalls[c]
1114+
let ret2 =
1115+
callees
1116+
|> List.map (fun callee -> getCallees {Caller.typeId = callee.typeId; funcType = callee.funcType})
1117+
|> List.fold Set.union Set.empty
1118+
Set.add c ret2
1119+
memo2.[c] <- result
1120+
result
1121+
getCallees_aux c
10641122

10651123
let ret =
10661124
seq {
@@ -1078,6 +1136,7 @@ let calculateFunctionToBeGenerated (r:Asn1AcnAst.AstRoot) (us:State) =
10781136
| true -> yield! getCallees caller
10791137
| false -> yield caller
10801138
} |> Set.ofSeq
1139+
printfn "Function calls detected: %d" ret.Count
10811140
match r.args.icdPdus with
10821141
| None -> ()
10831142
| Some _ ->
@@ -1130,5 +1189,7 @@ let DoWork (r:Asn1AcnAst.AstRoot) (icdStgFileName:string) (deps:Asn1AcnAst.AcnIn
11301189
acnParseResults = r.acnParseResults
11311190
deps = deps
11321191
icdHashes = ns.icdHashes
1133-
callersSet = calculateFunctionToBeGenerated r ns
1192+
callersSet =
1193+
detectPDUs r ns //this function will print the PDUs detected
1194+
calculateFunctionToBeGenerated r ns
11341195
}

BackendAst/DAstEqual.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ let createReferenceTypeEqualFunction (r:Asn1AcnAst.AstRoot) (lm:LanguageMacros)
346346
let ns =
347347
match t.id.topLevelTas with
348348
| None ->
349-
printfn "No type assignment info for %A" t.id
349+
//printfn "No type assignment info for %A" t.id
350350
us
351351
| Some tasInfo ->
352352
let caller = {Caller.typeId = tasInfo; funcType=EqualFunctionType}

BackendAst/DAstInitialize.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1253,7 +1253,7 @@ let createReferenceType (r:Asn1AcnAst.AstRoot) (lm:LanguageMacros) (t:Asn1AcnAst
12531253
let ns =
12541254
match t.id.topLevelTas with
12551255
| None ->
1256-
printfn "No type assignment info for %A" t.id
1256+
//printfn "No type assignment info for %A" t.id
12571257
us
12581258
| Some tasInfo ->
12591259
let caller = {Caller.typeId = tasInfo; funcType=InitFunctionType}

BackendAst/DastTestCaseCreation.fs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,11 @@ let emitDummyInitStatementsNeededForStatementCoverage (lm:Language.LanguageMacro
185185
Some (emitTestCaseAsFunc_dummy_init_function lm sTypeName initProc.funcName dummyVarName)
186186
| Some _ -> None)
187187

188+
let asn1EncodingMapping = function
189+
| UPER -> UperEncDecFunctionType
190+
| ACN -> AcnEncDecFunctionType
191+
| BER -> BerEncDecFunctionType
192+
| XER -> XerEncDecFunctionType
188193

189194
let printAllTestCasesAndTestCaseRunner (r:DAst.AstRoot) (lm:LanguageMacros) outDir =
190195
let tcFunctors =
@@ -196,7 +201,10 @@ let printAllTestCasesAndTestCaseRunner (r:DAst.AstRoot) (lm:LanguageMacros) outD
196201
match encDecTestFunc with
197202
| Some _ ->
198203
let hasEncodeFunc = e <> Asn1Encoding.ACN || hasAcnEncodeFunction t.Type.acnEncFunction t.Type.acnParameters t.Type.id.tasInfo
199-
if hasEncodeFunc then
204+
let typeAssignmentInfo = t.Type.id.tasInfo.Value
205+
let f cl = {Caller.typeId = typeAssignmentInfo; funcType = cl}
206+
let requiresTestCaseFunc = r.callersSet |> Set.contains (f (asn1EncodingMapping e))
207+
if hasEncodeFunc && requiresTestCaseFunc then
200208
let isTestCaseValid atc =
201209
match t.Type.acnEncFunction with
202210
| None -> false

BackendAst/GenerateFiles.fs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -316,14 +316,18 @@ let private printUnit (r:DAst.AstRoot) (lm:LanguageMacros) (encodings: CommonTy
316316
for tas in tases do
317317
let typeAssignmentInfo = tas.Type.id.tasInfo.Value
318318
let f cl = {Caller.typeId = typeAssignmentInfo; funcType = cl}
319-
let reqUPER = r.callersSet |> Set.contains (f UperEncDecFunctionType)
320-
let reqACN = r.callersSet |> Set.contains (f AcnEncDecFunctionType)
321-
322-
if reqUPER && r.args.encodings |> Seq.exists ((=) CommonTypes.UPER) then
319+
let reqUPER =
320+
r.args.encodings |> Seq.exists ((=) CommonTypes.UPER)
321+
&& r.callersSet |> Set.contains (f UperEncDecFunctionType)
322+
let reqACN =
323+
r.args.encodings |> Seq.exists ((=) CommonTypes.ACN)
324+
&& r.callersSet |> Set.contains (f AcnEncDecFunctionType)
325+
326+
if reqUPER then
323327
yield (tas.Type.uperEncDecTestFunc |> Option.map (fun z -> z.func))
324328
if r.args.encodings |> Seq.exists ((=) CommonTypes.XER) then
325329
yield (tas.Type.xerEncDecTestFunc |> Option.map (fun z -> z.func))
326-
if reqACN && r.args.encodings |> Seq.exists ((=) CommonTypes.ACN) then
330+
if reqACN then
327331
yield (tas.Type.acnEncDecTestFunc |> Option.map (fun z -> z.func))
328332
} |> Seq.choose id |> Seq.toList
329333

FrontEndAst/DAst.fs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ type FunctionType =
9292
| EqualFunctionType
9393
| UperEncDecFunctionType
9494
| AcnEncDecFunctionType
95+
| XerEncDecFunctionType
96+
| BerEncDecFunctionType
9597

9698

9799
type Caller = {

0 commit comments

Comments
 (0)