/** | |
******************************************************************************** | |
* 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(); | |
} | |
} |