Files
VisualSapfor/src/Repository/Component/Sapfor/Sapfor.java

598 lines
25 KiB
Java
Raw Normal View History

package Repository.Component.Sapfor;
2023-10-04 22:01:09 +03:00
import Common.Constants;
2023-09-17 22:13:42 +03:00
import Common.Current;
import Common.Global;
import Common.UI.UI;
import Common.Utils.Utils;
import GlobalData.Settings.SettingName;
import ProjectData.Files.DBProjectFile;
import ProjectData.Files.FileState;
import ProjectData.Files.LanguageStyle;
import ProjectData.Project.db_project_info;
import Repository.Component.OSDComponent;
import Repository.Component.Visualizer_2;
import Visual_DVM_2021.Passes.PassCode_2021;
import Visual_DVM_2021.Passes.PassException;
import Visual_DVM_2021.Passes.Pass_2021;
2023-09-17 22:13:42 +03:00
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.nio.charset.Charset;
2023-09-17 22:13:42 +03:00
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Vector;
public abstract class Sapfor extends OSDComponent {
public static final int empty_code = -100;
public static final int canceled_code = -99;
public static final int invalid_proj_code = -2;
public Vector<String> Intrinsics = new Vector<>();
public LinkedHashMap<String, String> ModifiedFiles = new LinkedHashMap<>();
public LinkedHashMap<String, String> OldFiles = new LinkedHashMap<>();
int size;
int[] sizes;
private int errorCode;
private String result;
private String output;
private String outputMessage;
private String predictorStats;
String PID = "";
//-
public static String pack(String... params) {
StringBuilder res = new StringBuilder();
for (String param : params)
res.append(param.length()).append(" ").append(param);
return res.toString();
}
public void refreshPid() {
try {
// UI.Info("Calling SPF_GetCurrentPID...");
RunAnalysis("SPF_GetCurrentPID", -1, "", "");
PID = getResult();
// UI.Info("PID = " + Utils.Brackets(PID));
} catch (Exception ex) {
ex.printStackTrace();
}
}
public static PassCode_2021[] getAnalysesCodes() {
return new PassCode_2021[]{
PassCode_2021.SPF_ParseFilesWithOrder,
PassCode_2021.SPF_GetFileLineInfo,
PassCode_2021.SPF_GetArrayDistributionOnlyRegions,
PassCode_2021.SPF_GetIncludeDependencies,
PassCode_2021.SPF_GetGraphLoops,
PassCode_2021.SPF_GetGraphFunctions,
PassCode_2021.SPF_GetAllDeclaratedArrays,
PassCode_2021.SPF_GetArrayDistributionOnlyAnalysis,
PassCode_2021.SPF_GetArrayDistribution
};
}
public static PassCode_2021[] getLoopsTransformationsCodes() {
return new PassCode_2021[]{
PassCode_2021.SPF_LoopEndDoConverterPass,
PassCode_2021.SPF_LoopFission,
PassCode_2021.SPF_LoopUnion,
PassCode_2021.SPF_LoopUnrolling
};
}
public static PassCode_2021[] getPrivatesTransformationsCodes() {
return new PassCode_2021[]{
PassCode_2021.SPF_PrivateShrinking,
PassCode_2021.SPF_PrivateExpansion,
PassCode_2021.SPF_PrivateRemoving
};
}
public static PassCode_2021[] getProceduresTransformationsCodes() {
return new PassCode_2021[]{
PassCode_2021.SPF_InlineProcedures,
PassCode_2021.SPF_InlineProceduresH,
PassCode_2021.SPF_DuplicateFunctionChains,
PassCode_2021.SPF_RemoveUnusedFunctions
};
}
public static PassCode_2021[] getDVMTransformationsCodes() {
return new PassCode_2021[]{
PassCode_2021.SPF_RemoveDvmDirectivesToComments,
2023-11-21 21:29:38 +03:00
PassCode_2021.SPF_RemoveDvmDirectives,
PassCode_2021.SPF_RemoveOmpDirectives
2023-09-17 22:13:42 +03:00
};
}
public static PassCode_2021[] getIntervalsTransformationsCodes() {
return new PassCode_2021[]{
PassCode_2021.SPF_CreateIntervalsTree,
PassCode_2021.SPF_RemoveDvmIntervals
};
}
public static PassCode_2021[] getRegionsTransformationsCodes() {
return new PassCode_2021[]{
PassCode_2021.SPF_ResolveParallelRegionConflicts,
PassCode_2021.SPF_InsertDvmhRegions
};
}
public static PassCode_2021[] getPreparationTransformationsCodes() {
return new PassCode_2021[]{
PassCode_2021.SPF_InsertIncludesPass,
PassCode_2021.SPF_CorrectCodeStylePass,
PassCode_2021.SPF_ConvertStructures,
PassCode_2021.SPF_CreateCheckpoints,
PassCode_2021.SPF_InitDeclsWithZero,
PassCode_2021.SPF_ExpressionSubstitution,
PassCode_2021.EraseBadSymbols,
PassCode_2021.CombineFiles,
PassCode_2021.CopyProject,
PassCode_2021.PrepareForModulesAssembly,
PassCode_2021.DVMConvertProject,
PassCode_2021.SPF_ResolveCommonBlockConflicts
};
}
public static Vector<PassCode_2021> getAllTransformationsCodes() {
Vector<PassCode_2021> res = new Vector<>();
Collections.addAll(res, getLoopsTransformationsCodes());
Collections.addAll(res, getPrivatesTransformationsCodes());
Collections.addAll(res, getProceduresTransformationsCodes());
Collections.addAll(res, getDVMTransformationsCodes());
Collections.addAll(res, getIntervalsTransformationsCodes());
Collections.addAll(res, getRegionsTransformationsCodes());
Collections.addAll(res, getPreparationTransformationsCodes());
return res;
}
//<editor-fold desc="компонент">
@Override
public void GetVersionInfo() {
try {
RunAnalysis("SPF_GetVersionAndBuildDate", -1, "", "");
Visualizer_2.UnpackVersionInfo(this, getResult());
} catch (Exception e) {
Global.Log.PrintException(e);
UI.Error("Не удалось получить версию компонента " + Utils.DQuotes(getComponentType().getDescription()));
}
}
public abstract String getUpdateCommand();
public abstract String getRestartCommand();
@Override
public void Update() throws Exception {
super.Update();
Global.visualizer_2.Command(getUpdateCommand());
GetVersionInfo();
ResetAllAnalyses();
refreshPid();
}
//</editor-fold>
//--------
//<editor-fold desc="функционал">
public String readStatForAnalyzer(String src) throws Exception {
RunAnalysis(
"SPF_OpenDvmStatistic",
-Global.messagesServer.getPort(),
Global.packSapforSettings(),
src);
return result;
}
public void readStatToTxt(File src, File dst) throws Exception {
RunAnalysis("SPF_StatisticAnalyzer",
-1,
"",
Utils.DQuotes(src.getAbsolutePath()) +
" "
+ Utils.DQuotes(dst.getAbsolutePath())
);
}
public void Restart() throws Exception {
ResetAllAnalyses();
Global.visualizer_2.Command(getRestartCommand());
refreshPid();
}
public void Interrupt() throws Exception {
Utils.Kill(PID, true);
}
public void cd(File directory_in) throws Exception {
if (RunAnalysis("SPF_ChangeDirectory", -1, directory_in.getAbsolutePath(), "") != 0)
throw new PassException("Sapfor: Не удалось перейти в папку "
+ Utils.Brackets(directory_in.getAbsolutePath()) +
"\n" + "Код возврата: " + getErrorCode());
}
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
public int getErrorCode() {
return errorCode;
}
public void setErrorCode(int errorCode) {
this.errorCode = errorCode;
}
public String getOutput() {
return output;
}
public void setOutput(String output) {
this.output = output;
}
public String getOutputMessage() {
return outputMessage;
}
public void setOutputMessage(String outputMessage) {
this.outputMessage = outputMessage;
}
public String getPredictorStats() {
return predictorStats;
}
public void setPredictorStats(String predictorStats) {
this.predictorStats = predictorStats;
}
public void decodeString(String runResult) throws Exception {
int codeIdx = runResult.indexOf(' ');
if (codeIdx == -1) throw new PassException("Wrong input parameter");
setErrorCode(Integer.parseInt(runResult.substring(0, codeIdx)));
int lastCodeIdx = 0, count = 0;
// for analysis and transformation
for (int z = 0; z < 4; ++z) {
lastCodeIdx = codeIdx;
codeIdx = runResult.indexOf(' ', codeIdx + 1);
if (codeIdx == -1) throw new PassException("Wrong input parameter");
count = Integer.parseInt(runResult.substring(lastCodeIdx + 1, codeIdx));
String sub = runResult.substring(codeIdx + 1, codeIdx + 1 + count);
if (z == 0) setResult(sub);
else if (z == 1) setOutput(sub);
else if (z == 2) setOutputMessage(sub);
else if (z == 3) setPredictorStats(sub);
codeIdx += count;
}
// for modification
String file_text = null;
if (codeIdx + 1 + count < runResult.length())
for (int z = 0; z < 3; ++z) {
lastCodeIdx = codeIdx;
codeIdx = runResult.indexOf(' ', codeIdx + 1);
if (codeIdx == -1) throw new PassException("Wrong input parameter");
count = Integer.parseInt(runResult.substring(lastCodeIdx + 1, codeIdx));
String sub = runResult.substring(codeIdx + 1, codeIdx + 1 + count);
if (z == 0) {
String[] splited = sub.split("\\|");
if (splited.length == 0 || sub.length() == 0)
size = 0;
else {
size = splited.length - 1;
sizes = new int[splited.length];
for (int k = 0; k < size + 1; ++k)
sizes[k] = Integer.parseInt(splited[k]);
}
} else if (z == 1) file_text = sub;
else if (z == 2) {
ModifiedFiles.put(Utils.toW(sub), file_text);
file_text = null;
}
codeIdx += count;
}
}
//-
public void Command(String request_in) throws Exception {
setErrorCode(empty_code);
outputMessage = output = result = predictorStats = "";
size = 0;
sizes = null;
ModifiedFiles.clear();
//модификации.-------------------------------------------------------------->>>>
decodeString(Global.visualizer_2.Command(request_in).replace((char) 1, '\n'));
}
//-
public int RunAnalysis(String analysisName,
int winHandler,
String options,
String projName) throws Exception {
Command("analysis:" + pack(analysisName, options, projName) + winHandler);
return getErrorCode();
}
public void RunTransformation(String transformName,
int winHandler,
String options,
String projName,
String folderName,
String addOpts) throws Exception {
Command("transformation:" + pack(transformName, options, projName, folderName, addOpts) + winHandler);
}
/*
Модификации:
SPF_ModifyArrayDistribution (addOpt1_c -> regId, addOpt2_c-> int64_t arrArrs, '|' as delimiter)
SPF_InlineProcedure (addOpt1_c -> name | file, addOpt2_c-> line)
*/
public void RunModification(String modifyName, int winHandler, String options, String projName,
String folderName, String addOpt1, String addOpt2) throws Exception {
Command("modification:" + pack(modifyName, options, projName, folderName, addOpt1, addOpt2) + winHandler);
}
public void GetIntrinsics() throws Exception {
Intrinsics.clear();
if (RunAnalysis("SPF_GetIntrinsics", -1, "", "") >= 0) {
String[] data = getResult().split(" ");
Collections.addAll(Intrinsics, data);
}
}
public boolean isIntrinsic(String func_name) {
return Intrinsics.contains(func_name.toLowerCase());
}
//todo рефакторить. отвязать от текущего проекта.
public void UpdateProjectFiles(boolean mode) throws Exception {
ResetAllAnalyses();
Current.getProject().dropLastModification();
DBProjectFile cuf = null;
if (Current.HasFile()) {
cuf = Current.getFile();
Pass_2021.passes.get(PassCode_2021.CloseCurrentFile).Do();
}
if (mode) //модификация
{
OldFiles.clear();
for (String name : ModifiedFiles.keySet()) {
if (Current.getProject().db.files.Data.containsKey(name)) {
File file = Current.getProject().db.files.Data.get(name).file;
OldFiles.put(name, Utils.ReadAllText(file));
Utils.WriteToFile(file, ModifiedFiles.get(name));
}
}
ModifiedFiles.clear();
} else //откат.
{
if (OldFiles.size() > 0) {
for (String name : OldFiles.keySet()) {
File file = Current.getProject().db.files.Data.get(name).file;
Utils.WriteToFile(file, OldFiles.get(name));
}
OldFiles.clear();
} else UI.Info("Сохранение файлов отсутствует.");
}
if (cuf != null)
Pass_2021.passes.get(PassCode_2021.OpenCurrentFile).Do(cuf);
}
//</editor-fold>
public Visual_DVM_2021.Passes.SapforAnalysis getAnalysisByPhase(String phase) {
2023-09-17 22:13:42 +03:00
for (PassCode_2021 analysis_code : getAnalysesCodes()) {
Visual_DVM_2021.Passes.SapforAnalysis analysis = (Visual_DVM_2021.Passes.SapforAnalysis) Pass_2021.passes.get(analysis_code);
2023-09-17 22:13:42 +03:00
if (analysis.phase().equals(phase)) return analysis;
}
return null;
}
public void ResetAllAnalyses() {
for (PassCode_2021 code : getAnalysesCodes())
(Pass_2021.passes.get(code)).Reset();
//------------------------------------------------------------------------------------------>>>> пакетный режим.
if (Current.hasUI()) {
Pass_2021.passes.get(PassCode_2021.Precompilation).Reset();
Pass_2021.passes.get(PassCode_2021.SPF_GetGCovInfo).Reset();
}
Global.enable_text_changed = false;
Global.transformationPermission = TransformationPermission.None;
if ((Current.hasUI()) && (UI.getMainWindow() != null) && (UI.getVersionsWindow() != null))
UI.getVersionsWindow().BlockVariants();
}
//--------------------------------------------------------------------------->>
//временный (?) проход, по тихому получить размерность теста, предварительно выполнив тихий парс.
//тут все одноразовое. считаем что таблицы бд уже заполнены как надо.
public LanguageStyle getStyle() throws Exception {
return Global.getSetting(SettingName.FREE_FORM).toBoolean() ? LanguageStyle.free : LanguageStyle.fixed;
}
//----------
public static Vector<PassCode_2021> getScenariosCodes() {
Vector<PassCode_2021> res = new Vector<>();
res.add(PassCode_2021.SPF_InitDeclsWithZero);
res.add(PassCode_2021.SPF_ConvertStructures);
res.add(PassCode_2021.SPF_ExpressionSubstitution);
//--
res.add(PassCode_2021.SPF_CreateCheckpoints);
res.add(PassCode_2021.SPF_CreateIntervalsTree);
res.add(PassCode_2021.SPF_RemoveDvmIntervals);
//--
res.add(PassCode_2021.SPF_RemoveDvmDirectives);
res.add(PassCode_2021.SPF_RemoveDvmDirectivesToComments);
res.add(PassCode_2021.SPF_RemoveOmpDirectives);
//--
res.add(PassCode_2021.SPF_LoopEndDoConverterPass);
res.add(PassCode_2021.SPF_LoopUnion);
res.add(PassCode_2021.SPF_LoopFission);
//--
res.add(PassCode_2021.SPF_PrivateShrinking);
res.add(PassCode_2021.SPF_PrivateExpansion);
res.add(PassCode_2021.SPF_PrivateRemoving);
//--
res.add(PassCode_2021.SPF_RemoveUnusedFunctions);
res.add(PassCode_2021.SPF_DuplicateFunctionChains);
//--
res.add(PassCode_2021.SPF_ResolveParallelRegionConflicts);
res.add(PassCode_2021.SPF_ResolveCommonBlockConflicts);
//-
res.add(PassCode_2021.SPF_InsertDvmhRegions);
res.add(PassCode_2021.SPF_SharedMemoryParallelization);
res.add(PassCode_2021.CreateParallelVariants);
// res.add(PassCode_2021.SPF_InlineProceduresH);
// res.add(PassCode_2021.SPF_InlineProcedures);
// res.add(PassCode_2021.SPF_InsertIncludesPass);
return res;
}
//--
2023-09-17 22:13:42 +03:00
public int getTextMaxDim(File testFile, db_project_info target) {
2023-09-29 21:46:08 +03:00
int res = Constants.Nan;
2023-09-17 22:13:42 +03:00
LinkedHashMap<String, DBProjectFile> files = null;
if (testFile != null) {
DBProjectFile dbProjectFile = new DBProjectFile(testFile, target);
files = new LinkedHashMap<>();
files.put(dbProjectFile.name, dbProjectFile);
} else
files = target.db.files.Data;
Vector<String> projLines = new Vector<>();
try {
target.CreateParserOptionsDirs();
//-----
Restart();
cd(target.Home);
//-----
//<editor-fold desc="создание proj">
for (DBProjectFile f : files.values()) {
if (f.isActiveProgram()) {
projLines.add(Utils.toU(f.file.getAbsolutePath()));
f.CreateParserOptions();
}
}
FileUtils.writeLines(target.getProjFile(), projLines, false);
//</editor-fold>
//-----
RunAnalysis(
"SPF_ParseFilesWithOrder",
-Global.messagesServer.getPort(),
Global.packSapforSettings(),
target.getProjFile().getAbsolutePath());
if (errorCode >= 0) {
projLines.clear();
int goodCount = 0;
int badCount = 0;
for (DBProjectFile f : files.values())
if (f.isActive()) f.state = FileState.OK;
for (DBProjectFile f : files.values()) {
f.ReadParseMessagesNoSave(files);
if (f.isActive()) {
switch (f.state) {
case OK:
case HasNotes:
case HasWarnings:
if (f.isActiveProgram())
projLines.add(Utils.toU(f.getDepFile().getAbsolutePath()));
goodCount++;
break;
case HasErrors:
badCount++;
break;
default:
break;
}
}
}
FileUtils.writeLines(target.getProjFile(), projLines, false);
if (badCount > 0) return res;
if (goodCount == 0) return res;
} else return res;
//---
Restart();
cd(target.Home);
///---
RunAnalysis(
"SPF_GetMaxMinBlockDistribution",
-Global.messagesServer.getPort(),
Global.packSapforSettings(),
target.getProjFile().getAbsolutePath());
if ((errorCode < 0) || target.hasErrorMessages(getOutputMessage()))
return res;
//--
System.out.println(Utils.Brackets(getResult()));
String[] data = getResult().split(" ");
target.CreateParserOptionsDirs(); // теперь очистка.
return Integer.parseInt(data[data.length - 1]);
///---
} catch (Exception ex) {
ex.printStackTrace();
}
return res;
}
//--
//------------------------------------------------------------------------------------------------------------------
public String getConsoleFlags() throws Exception {
Vector<String> res = new Vector<>();
if (Global.getSetting(SettingName.FREE_FORM).toBoolean())
res.add("-f90");
if (Global.getSetting(SettingName.STATIC_SHADOW_ANALYSIS).toBoolean())
res.add("-sh");
res.add("-shwidth " + Global.getSetting(SettingName.MAX_SHADOW_WIDTH));
if (Global.getSetting(SettingName.KEEP_SPF_DIRECTIVES).toBoolean())
res.add("-keepSPF");
return String.join(" ", res);
}
public static boolean checkLines(Vector<String> lines) {
for (String line : lines) {
if (line.toLowerCase().contains("internal error")) {
return false;
}
if (line.toLowerCase().contains("exception")) {
return false;
}
if (line.contains("[ERROR]")) {
return false;
}
if (line.toLowerCase().contains("segmentation fault")) {
return false;
}
}
return true;
}
public static boolean performScript(String name, //имя скрипта
File sapfor_drv, //путь к сапфору
File workspace, //проект
String command, //проход
String flags, //флаги
String outName,
String errName) throws Exception {
Process process = null;
int exit_code = Constants.Nan;
//---
File data_workspace = new File(workspace, Constants.data);
Utils.CheckDirectory(data_workspace);
File outputFile = new File(data_workspace, outName);
File errorsFile = new File(data_workspace, errName);
Utils.delete_with_check(outputFile);
Utils.delete_with_check(errorsFile);
//---
File file = new File(data_workspace, name + (Global.isWindows ? ".bat" : ".sh"));
System.out.println(file.getAbsolutePath());
FileUtils.write(file,
Utils.DQuotes(sapfor_drv)
+ (flags.isEmpty() ? "" : (" " + flags))
+ " -noLogo"
+ " " + command +
" 1>" +
Utils.DQuotes(outputFile.getAbsolutePath()) +
" 2>" +
Utils.DQuotes(errorsFile.getAbsolutePath()),
Charset.defaultCharset());
if (!file.setExecutable(true))
throw new Exception("Не удалось сделать файл скрипта " + name + " исполняемым!");
//--
boolean flag = false;
do {
try {
ProcessBuilder procBuilder = new ProcessBuilder(file.getAbsolutePath());
procBuilder.directory(workspace);
process = procBuilder.start();
exit_code = process.waitFor();
flag = true;
} catch (Exception ex) {
Global.Log.PrintException(ex);
Utils.sleep(1000);
}
}
while (!flag);
process = null;
//---
Vector<String> outputLines = new Vector<>(FileUtils.readLines(outputFile));
Vector<String> errorsLines = new Vector<>(FileUtils.readLines(errorsFile));
return (exit_code == 0) &&
checkLines(outputLines) &&
checkLines(errorsLines);
}
public static boolean parse(File sapfor_drv, File workspace, String flags) throws Exception {
return performScript(
"parse",
sapfor_drv,
workspace,
"-parse *.f *.for *.fdv *.f90 *.f77",
flags,
Constants.parse_out_file,
Constants.parse_err_file)
&& (new File(workspace, "dvm.proj")).exists();
}
public static boolean analysis(File sapfor_drv, File workspace, PassCode_2021 code, String flags) throws Exception {
return performScript("analysis",
sapfor_drv,
workspace,
code.getTestingCommand(),
flags,
Constants.out_file,
Constants.err_file);
}
2023-09-17 22:13:42 +03:00
}