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

604 lines
25 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package Repository.Component.Sapfor;
import Common.Constants;
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;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.nio.charset.Charset;
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,
PassCode_2021.SPF_RemoveDvmDirectives,
PassCode_2021.SPF_RemoveOmpDirectives
};
}
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) {
for (PassCode_2021 analysis_code : getAnalysesCodes()) {
Visual_DVM_2021.Passes.SapforAnalysis analysis = (Visual_DVM_2021.Passes.SapforAnalysis) Pass_2021.passes.get(analysis_code);
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;
}
//--
public int getTextMaxDim(File testFile, db_project_info target) {
int res = Constants.Nan;
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 Vector<String> outputLines = null;
public static Vector<String> errorsLines = null;
//---
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);
outputLines = null;
errorsLines = null;
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;
//---
outputLines = new Vector<>(FileUtils.readLines(outputFile));
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);
}
}