blob: 9258eed9f6aaaee5aaeced227e268061d7dabeef [file] [log] [blame]
/**
********************************************************************************
* Copyright (c) 2017-2020 Robert Bosch GmbH and others.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Robert Bosch GmbH - initial API and implementation
********************************************************************************
*/
package org.eclipse.app4mc.sca2amalthea.llvm.headless;
import java.io.IOException;
import java.util.List;
import java.util.Locale;
import org.eclipse.app4mc.amalthea.model.Amalthea;
import org.eclipse.app4mc.sca.amalthea.serializer.AMALTHEAResourceSerializer;
import org.eclipse.app4mc.sca.logging.manager.LogFactory.Severity;
import org.eclipse.app4mc.sca.logging.util.LogUtil;
import org.eclipse.app4mc.sca.scheduling.loader.model.OSConfModel;
import org.eclipse.app4mc.sca.scheduling.loader.model.SchedulingInformationLoader;
import org.eclipse.app4mc.sca.util.App4mcToolConstants;
import org.eclipse.app4mc.sca.util.util.SCAToolsDirectoryType;
import org.eclipse.app4mc.sca.util.util.SCAUtils;
import org.eclipse.app4mc.sca.util.workspaces.WorkspaceOperations;
import org.eclipse.app4mc.sca2amalthea.exporter.SCAToAmaltheaExporter;
import org.eclipse.app4mc.sca2amalthea.exporter.locks.LockDefinition;
import org.eclipse.app4mc.sca2amalthea.exporter.util.LLVMLogUtil;
import org.eclipse.app4mc.sca2amalthea.ir.loader.SCAIRLoader;
import org.eclipse.app4mc.sca2amalthea.llvm.Activator;
import org.eclipse.app4mc.sca2amalthea.llvm.srcfiles.support.CFilesListProvider;
import org.eclipse.app4mc.sca2amalthea.llvm.srcfiles.support.PathsToListConverter;
import org.eclipse.app4mc.sca2amalthea.llvm.starter.GenerateTraverseAstOutput;
import org.eclipse.app4mc.sca2amalthea.llvm.starter.LLVMStarterProperties;
import org.eclipse.app4mc.sca2amalthea.llvm.util.ManipulateAmalthea;
import org.eclipse.app4mc.sca2amalthea.scairmodelenricher.SCAIRModelEnrichmentUtils;
import org.eclipse.app4mc.sca2amalthea.serialization.SCAResource;
import org.eclipse.app4mc.sca2amalthea.utils.UtilityForProcessHandling;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.util.URI;
import com.google.common.base.Strings;
public class GenerateAmaltheaModelFromLLVM {
private final SCA2AMALTHEAStarterProperties sca2amProperties;
private long startTime = System.currentTimeMillis();
/**
* Generates amalthea model from the given properties. The given properties are used to populate the ast model and
* from the ast model the intermediate representation. The intermdediate representation is inturn used to generate the
* amalthea model
*
* @param llvmProperties {@link LLVMStarterProperties}
*/
public GenerateAmaltheaModelFromLLVM(final SCA2AMALTHEAStarterProperties llvmProperties) {
super();
this.sca2amProperties = llvmProperties;
}
/**
* @throws IOException IOException
* @throws InterruptedException InterruptedException
* @return int status of the amalthea model generation
*/
public IStatus run() throws IOException, InterruptedException {
IStatus status = Status.OK_STATUS;
this.startTime = System.currentTimeMillis();
LogUtil.log(LLVMLogUtil.LOG_MSG_ID, Severity.INFO,
"Starting sca2amalthea export... [start time " + this.startTime + "]", this.getClass(), Activator.PLUGIN_ID);
applyFallBackStrategy();
if (isXmlCallTreeProvided()) {
convertXMLToAmaltheaModel(this.sca2amProperties.getPathToxmlCallTree());
}
else {
findAndParseCFiles();
if (UtilityForProcessHandling.isCurrentRunningProcessSuccessful()) {
String xmlCallTreePath =
this.sca2amProperties.getLlvmStarterProperties().getGenDirectory() + "/XMLCalltree.xml";
convertXMLToAmaltheaModel(xmlCallTreePath);
WorkspaceOperations.refreshWorkspace(this.sca2amProperties.getProjectPath(), "_bin/sca2amalthea");
WorkspaceOperations.refreshWorkspace(this.sca2amProperties.getProjectPath(), "_log/sca2amalthea");
WorkspaceOperations.refreshWorkspace(this.sca2amProperties.getProjectPath(), "_gen/sca2amalthea");
}
else {
status = Status.CANCEL_STATUS;
LogUtil.log(LLVMLogUtil.LOG_MSG_ID, Severity.INFO, "AMALTHEA model generation aborted.", this.getClass(),
Activator.PLUGIN_ID);
}
}
return status;
}
private void convertXMLToAmaltheaModel(final String xmlCallTreePath) {
LogUtil.log(LLVMLogUtil.LOG_MSG_ID, Severity.INFO, "Transforming the intermediate representation to amalthea model",
this.getClass(), Activator.PLUGIN_ID);
OSConfModel osConfModel = null;
URI createURI = URI.createFileURI(xmlCallTreePath);
SCAResource resource = new SCAIRLoader().load(createURI);
if ((this.sca2amProperties.getTaskListFile() != null) && !this.sca2amProperties.getTaskListFile().isEmpty()) {
SchedulingInformationLoader schedInfoLoader = new SchedulingInformationLoader();
osConfModel = schedInfoLoader.getTasksInformation(this.sca2amProperties.getTaskListFile());
if (osConfModel != null) {
SCAIRModelEnrichmentUtils.markTasksIsrsRunnablesInModel(resource, osConfModel.getTaskISRInfoAsMap());
}
}
LockDefinition lockDefinition = null;
if ((this.sca2amProperties.getLockinfoFile() != null) && !this.sca2amProperties.getLockinfoFile().isEmpty()) {
lockDefinition = new LockDefinition(this.sca2amProperties.getLockinfoFile());
lockDefinition.readLockDefinitionFromFile();
}
Amalthea amaltheaModel = new SCAToAmaltheaExporter().amaltheaTransformation(resource, lockDefinition, osConfModel);
ManipulateAmalthea.markIniTasksInAmaltheaModel(amaltheaModel, osConfModel);
ManipulateAmalthea manipulatorCaller = new ManipulateAmalthea();
manipulatorCaller.manipulates(this.sca2amProperties, amaltheaModel);
AMALTHEAResourceSerializer amResSerializer = new AMALTHEAResourceSerializer();
amResSerializer.saveAmaltheaModel(this.sca2amProperties.getBinDirectory() + "/amaltheaModelFromLLVM",
amaltheaModel);
long duration = (System.currentTimeMillis() - this.startTime) / 1000; // in seconds
LogUtil.log(LLVMLogUtil.LOG_MSG_ID, Severity.INFO,
"Export of AMALTHEA model completed. [duration=" + duration + " seconds]", this.getClass(),
Activator.PLUGIN_ID);
}
/**
* Method that provides the fall back strategy if the user has not provided the necessary parameters
*/
private void applyFallBackStrategy() {
if ((this.sca2amProperties.getOutPutPath() == null) || this.sca2amProperties.getOutPutPath().isEmpty()) {
this.sca2amProperties.setBinDirectory(SCAUtils.getSCARootDirectory(this.sca2amProperties.getProjectPath(),
SCAToolsDirectoryType.SCA_BIN, App4mcToolConstants.SCA2AMALTHEA_TOOL_ID.toLowerCase(Locale.getDefault())));
this.sca2amProperties.getLlvmStarterProperties().setGenDirectory(
SCAUtils.getSCARootDirectory(this.sca2amProperties.getProjectPath(), SCAToolsDirectoryType.SCA_GEN,
App4mcToolConstants.SCA2AMALTHEA_TOOL_ID.toLowerCase(Locale.getDefault())));
this.sca2amProperties.getLlvmStarterProperties().setLogDirecotry(
SCAUtils.getSCARootDirectory(this.sca2amProperties.getProjectPath(), SCAToolsDirectoryType.SCA_LOG,
App4mcToolConstants.SCA2AMALTHEA_TOOL_ID.toLowerCase(Locale.getDefault())));
}
else {
this.sca2amProperties.setBinDirectory(this.sca2amProperties.getOutPutPath());
this.sca2amProperties.getLlvmStarterProperties().setGenDirectory(this.sca2amProperties.getOutPutPath());
this.sca2amProperties.getLlvmStarterProperties().setLogDirecotry(this.sca2amProperties.getOutPutPath());
}
}
/**
* This method checks if the user has provided the c files list text file and the header directories. If so it reads them
* and generates the clist and hlist.
*/
private void parseCFilesListAndHDirListOptions() {
List<String> cList;
if ((this.sca2amProperties.getcFilesListTxtFilePath() != null) && !this.sca2amProperties.getcFilesListTxtFilePath().isEmpty()) {
CFilesListProvider cListProvider = new CFilesListProvider(this.sca2amProperties.getcFilesListTxtFilePath(),
this.sca2amProperties.getProjectPath());
cList = cListProvider.generateSourceFileList();
this.sca2amProperties.setcFilesList(cList);
}
List<String> hList;
if ((this.sca2amProperties.gethDirFilePath() != null) && !this.sca2amProperties.gethDirFilePath().isEmpty()) {
String hFilePathList = this.sca2amProperties.gethDirFilePath();
// create h file list
hList = new PathsToListConverter(hFilePathList, ".h").generateSourceFileList();
this.sca2amProperties.sethFilesList(hList);
}
}
private boolean isXmlCallTreeProvided() {
return !Strings.isNullOrEmpty(this.sca2amProperties.getPathToxmlCallTree());
}
private void findAndParseCFiles() throws IOException, InterruptedException {
parseCFilesListAndHDirListOptions();
GenerateTraverseAstOutput llvmStarter =
new GenerateTraverseAstOutput(this.sca2amProperties.getLlvmStarterProperties());
llvmStarter.runTraverseAst();
}
}