OpenASIP 2.2
Loading...
Searching...
No Matches
Classes | Public Member Functions | Static Public Attributes | Protected Member Functions | Static Protected Member Functions | Protected Attributes | Private Types | Private Member Functions | Private Attributes | Static Private Attributes | List of all members
llvm::LLVMTCEBuilder Class Referenceabstract

#include <LLVMTCEBuilder.hh>

Inheritance diagram for llvm::LLVMTCEBuilder:
Inheritance graph
Collaboration diagram for llvm::LLVMTCEBuilder:
Collaboration graph

Classes

struct  ConstantDataDef
 Data definition structure for constant pool values. More...
 
struct  DataDef
 Data definition structure for global values. More...
 

Public Member Functions

 LLVMTCEBuilder (char &ID)
 
 LLVMTCEBuilder (const TargetMachine &tm, TTAMachine::Machine *mach, char &ID, bool functionAtATime=false)
 
virtual ~LLVMTCEBuilder ()
 
TTAProgram::Programresult ()
 
TTAProgram::InstructionfirstInstructionOfBasicBlock (const llvm::BasicBlock *bb)
 
bool isProgramUsingRestrictedPointers () const
 
virtual void getAnalysisUsage (AnalysisUsage &AU) const
 
virtual bool isTTATarget () const
 
void deleteDeadProcedures ()
 
void setInitialStackPointerValue (unsigned value)
 

Static Public Attributes

static char ID = 0
 

Protected Member Functions

bool doInitialization (Module &M)
 
bool runOnMachineFunction (MachineFunction &MF)
 
bool doFinalization (Module &M)
 
bool hasAmbiguousASpaceRefs (const TTAProgram::Instruction &instr) const
 
virtual bool writeMachineFunction (MachineFunction &MF)
 
void initDataSections ()
 
std::shared_ptr< TTAProgram::MovecreateMove (const MachineOperand &src, const MachineOperand &dst, TTAProgram::MoveGuard *guard)
 
const TargetMachine & targetMachine () const
 
virtual unsigned spDRegNum () const =0
 
virtual unsigned raPortDRegNum () const =0
 
virtual TCEString registerFileName (unsigned llvmRegNum) const =0
 
virtual int registerIndex (unsigned llvmRegNum) const =0
 
TCEString registerName (unsigned llvmRegNum) const
 
virtual TCEString operationName (const MachineInstr &mi) const =0
 
virtual TTAProgram::TerminalcreateFUTerminal (const MachineOperand &) const
 
std::string mbbName (const MachineBasicBlock &mbb)
 
const TTAMachine::HWOperationgetHWOperation (std::string opName)
 
TTAProgram::TerminalRegistercreateTerminalRegister (const std::string &rfName, int index)
 
TTAProgram::TerminalcreateTerminal (const MachineOperand &mo, int bitLimit=0)
 
std::shared_ptr< TTAProgram::MovecreateMove (TTAProgram::Terminal *src, TTAProgram::Terminal *dst, const TTAMachine::Bus &bus, TTAProgram::MoveGuard *guard=NULL)
 
void emitConstantPool (const llvm::MachineConstantPool &cp)
 
virtual TTAProgram::TerminalcreateMBBReference (const MachineOperand &mo)
 
virtual TTAProgram::TerminalcreateSymbolReference (const MachineOperand &mo)
 
virtual TTAProgram::TerminalcreateProgramOperationReference (const MachineOperand &mo)
 
virtual TTAProgram::TerminalcreateSymbolReference (const TCEString &symbolName)
 
TTAProgram::InstructionemitInstruction (const MachineInstr *mi, TTAProgram::CodeSnippet *proc)
 
virtual TTAProgram::InstructionemitMove (const MachineInstr *mi, TTAProgram::CodeSnippet *proc, bool conditional=false, bool trueGuard=true)
 
TTAProgram::InstructionemitInlineAsm (const MachineFunction &mf, const MachineInstr *mi, TTAProgram::BasicBlock *bb, TTAProgram::InstructionReferenceManager &irm)
 
void fixProgramOperationReferences ()
 
void addLabelForProgramOperation (TCEString label, ProgramOperationPtr po)
 
virtual void emitSPInitialization ()
 
void emitSPInitialization (TTAProgram::CodeSnippet &target)
 
void clearFunctionBookkeeping ()
 

Static Protected Member Functions

static bool isInlineAsm (const MachineInstr &instr)
 

Protected Attributes

std::map< std::string, TTAProgram::Instruction * > codeLabels_
 Code labels.
 
TTAMachine::Machinemach_
 Machine for building the program.
 
const llvm::TargetMachine * tm_
 Target machine description.
 
llvm::Mangler * mang_
 Mangler for mangling label strings.
 
TTAProgram::Programprog_
 Current program being built.
 
std::set< std::string > opset_
 The operations supported by the current target machine.
 
bool functionAtATime_
 
PRegionMarkerAnalyzerpregions_
 
int spillMoveCount_
 
unsigned initialStackPointerValue_
 
MachineFrameInfo * curFrameInfo_
 
LLVMTCECmdLineOptionsoptions_ = nullptr
 The compiler options.
 

Private Types

typedef std::map< TTAMachine::AddressSpace *, TTAProgram::DataMemory * > DataMemIndex
 

Private Member Functions

void initMembers ()
 
void emitDataDef (const DataDef &def)
 
void emitDataDef (const ConstantDataDef &def)
 
unsigned createDataDefinition (int addressSpaceId, unsigned &addr, const Constant *cv, bool forceInitialize=false, unsigned forceAlignment=0)
 
void createIntDataDefinition (int addressSpaceId, unsigned &addr, const llvm::ConstantInt *ci, bool isPointer=false)
 
void createFPDataDefinition (int addressSpaceId, unsigned &addr, const llvm::ConstantFP *cfp)
 
void createGlobalValueDataDefinition (int addressSpaceId, unsigned &addr, const GlobalValue *gv, int offset=0)
 
void createExprDataDefinition (int addressSpaceId, unsigned &addr, const ConstantExpr *gv, int offset=0)
 
void padToAlignment (int addressSpaceId, unsigned &addr, unsigned align)
 
TTAProgram::TerminalcreateAddrTerminal (const MachineOperand &base, const MachineOperand &offset)
 
TTAProgram::InstructionemitLoad (const MachineInstr *mi, TTAProgram::CodeSnippet *proc)
 
TTAProgram::InstructionemitStore (const MachineInstr *mi, TTAProgram::CodeSnippet *proc)
 
TTAProgram::InstructionemitReturn (const MachineInstr *mi, TTAProgram::CodeSnippet *proc)
 
TTAProgram::InstructionemitOperationMacro (const MachineInstr *mi, TTAProgram::CodeSnippet *proc)
 
TTAProgram::InstructionemitSpecialInlineAsm (const std::string op, const MachineInstr *mi, TTAProgram::CodeSnippet *proc)
 
TTAProgram::InstructionemitSetjmp (const MachineInstr *mi, TTAProgram::CodeSnippet *proc)
 
TTAProgram::InstructionemitLongjmp (const MachineInstr *mi, TTAProgram::CodeSnippet *proc)
 
TTAProgram::InstructionemitSelect (const MachineInstr *mi, TTAProgram::CodeSnippet *proc)
 
TTAProgram::InstructionemitGlobalXXtructorCalls (const MachineInstr *mi, TTAProgram::CodeSnippet *proc, bool constructors)
 
TTAProgram::InstructionemitReadSP (const MachineInstr *mi, TTAProgram::CodeSnippet *proc)
 
TTAProgram::InstructionemitWriteSP (const MachineInstr *mi, TTAProgram::CodeSnippet *proc)
 
TTAProgram::InstructionemitReturnTo (const MachineInstr *mi, TTAProgram::CodeSnippet *proc)
 
TTAProgram::InstructionhandleMemoryCategoryInfo (const MachineInstr *mi, TTAProgram::CodeSnippet *proc)
 
TTAProgram::InstructionemitComparisonForBranch (TCEString firstOp, const MachineInstr *mi, TTAProgram::CodeSnippet *proc)
 
TTAProgram::InstructionemitRemaingingBrach (TCEString opName, const MachineInstr *mi, TTAProgram::CodeSnippet *proc)
 
void createSPInitLoad (TTAProgram::CodeSnippet &target, TTAProgram::Terminal &src, TTAProgram::Terminal &dst)
 
bool isInitialized (const Constant *cv)
 
TTAProgram::MoveGuardcreateGuard (const TTAProgram::Terminal *guardReg, bool trueOrFalse)
 
void debugDataToAnnotations (const llvm::MachineInstr *mi, TTAProgram::Move &move)
 
void addPointerAnnotations (const llvm::MachineInstr *mi, TTAProgram::Move &move)
 
bool isBaseOffsetMemOperation (const Operation &operation) const
 
virtual void createMoveNode (ProgramOperationPtr &, std::shared_ptr< TTAProgram::Move > m, bool)
 
unsigned addressSpaceId (TTAMachine::AddressSpace &aSpace) const
 
TTAMachine::AddressSpaceaddressSpaceById (unsigned id)
 
unsigned & dataEnd (TTAMachine::AddressSpace &aSpace)
 
void addCandidateLSUAnnotations (unsigned asNum, TTAProgram::Move &move)
 
TTAProgram::DataMemorydataMemoryForAddressSpace (TTAMachine::AddressSpace &aSpace)
 
void copyFUAnnotations (const std::vector< TTAProgram::Instruction * > &operandMoves, TTAProgram::Move &move) const
 
std::string getAsmString (const MachineInstr &mi) const
 

Private Attributes

llvm::Module * mod_
 
TTAMachine::AddressSpaceinstrAddressSpace_
 
TTAMachine::AddressSpacedefaultDataAddressSpace_
 The default data memory address space (address space 0).
 
bool multiDataMemMachine_
 Set to true in case this machine has more than one data address spaces.
 
DataMemIndex dmemIndex_
 
std::vector< DataDefdata_
 Data definitions.
 
std::vector< DataDefudata_
 
std::vector< ConstantDataDefcpData_
 
std::map< std::string, TTAProgram::Instruction * > mbbs_
 Machine basic block -> first instruction in the BB map.
 
std::map< const llvm::BasicBlock *, TTAProgram::Instruction * > bbIndex_
 Basic Block -> first instruction in the BB map.
 
std::map< std::string, unsigned > dataLabels_
 Data labels.
 
std::map< TTAProgram::TerminalInstructionAddress *, std::string > codeLabelReferences_
 Dummy code label references that have to be fixed after all instrutions have been built.
 
std::map< TTAProgram::TerminalInstructionAddress *, std::string > mbbReferences_
 Dummy basic block references that have to be fixed after all basic blocks have been built.
 
std::vector< std::shared_ptr< TTAProgram::Move > > endReferences_
 Dummy references to the _end symbol.
 
std::map< const llvm::Constant *, unsigned > globalCP_
 Global constant pool for all constants gathered from machine functions. Map key is unique constant and the value is address of the constant.
 
std::map< unsigned, unsigned > currentFnCP_
 Constant pool for the current machine function. Map key is constant pool index and the value is address.
 
std::map< TTAMachine::AddressSpace *, unsigned > dataEnds_
 The first position after the last data in the given address space.
 
bool noAliasFound_
 set to true in case at least one 'noalias' attribute (from the use of 'restricted' pointers) has been found
 
bool multiAddrSpacesFound_
 set to true in case at least one non-default address space memory access has been found in the generated code
 
std::vector< MachineFunction * > functions_
 List of machine functions collected from runForMachineFunction.
 
bool dataInitialized_
 
std::set< TTAProgram::TerminalProgramOperation * > symbolicPORefs_
 
std::map< TCEString, ProgramOperationPtrlabeledPOs_
 
const llvm::DataLayout * dl_
 The data layout for the machine.
 

Static Private Attributes

static unsigned MAU_BITS = 8
 Target architechture MAU size in bits.
 
static unsigned POINTER_SIZE_32 = 4
 Target architecture pointer size in maus.
 
static unsigned POINTER_SIZE_64 = 8
 

Detailed Description

Base class for the various LLVM to TCE builder implementations.

Definition at line 102 of file LLVMTCEBuilder.hh.

Member Typedef Documentation

◆ DataMemIndex

Definition at line 299 of file LLVMTCEBuilder.hh.

Constructor & Destructor Documentation

◆ LLVMTCEBuilder() [1/2]

LLVMTCEBuilder::LLVMTCEBuilder ( char &  ID)

Definition at line 167 of file LLVMTCEBuilder.cc.

167 : MachineFunctionPass(ID) {
168 initMembers();
169}

References initMembers().

Here is the call graph for this function:

◆ LLVMTCEBuilder() [2/2]

LLVMTCEBuilder::LLVMTCEBuilder ( const TargetMachine &  tm,
TTAMachine::Machine mach,
char &  ID,
bool  functionAtATime = false 
)

Definition at line 154 of file LLVMTCEBuilder.cc.

158 :
159 MachineFunctionPass(ID) {
160 initMembers();
161 tm_ = &tm;
162 mach_ = mach;
163 functionAtATime_ = functionAtATime;
164 dl_ = new DataLayout(tm_->createDataLayout());
165}
TTAMachine::Machine * mach_
Machine for building the program.
const llvm::TargetMachine * tm_
Target machine description.
const llvm::DataLayout * dl_
The data layout for the machine.

References dl_, functionAtATime_, initMembers(), mach_, and tm_.

Here is the call graph for this function:

◆ ~LLVMTCEBuilder()

LLVMTCEBuilder::~LLVMTCEBuilder ( )
virtual

The Destructor.

Definition at line 196 of file LLVMTCEBuilder.cc.

196 {
197 if (mang_ != NULL) {
198 delete mang_;
199 mang_ = NULL;
200 }
201}
llvm::Mangler * mang_
Mangler for mangling label strings.

References mang_.

Member Function Documentation

◆ addCandidateLSUAnnotations()

void LLVMTCEBuilder::addCandidateLSUAnnotations ( unsigned  asNum,
TTAProgram::Move move 
)
private

Adds annotations to the given move that limit the choice of the load-store unit to only those that support the given address space.

Definition at line 3834 of file LLVMTCEBuilder.cc.

3835 {
3836
3837 TCEString opName;
3838 if (move.destination().isFUPort()) {
3839 opName = dynamic_cast<TTAProgram::TerminalFUPort&>(
3840 move.destination()).hwOperation()->name();
3841 } else {
3842 opName = dynamic_cast<TTAProgram::TerminalFUPort&>(
3843 move.source()).hwOperation()->name();
3844 }
3845 bool foundLSU = false;
3848 for (int i = 0; i < fuNav.count(); i++) {
3849 const TTAMachine::FunctionUnit& fu = *fuNav.item(i);
3850 if (fu.hasAddressSpace()) {
3851 if (fu.addressSpace()->hasNumericalId(asNum) &&
3852 fu.hasOperation(opName)) {
3853 TTAProgram::ProgramAnnotation progAnnotation(
3855 ANN_ALLOWED_UNIT_DST, fu.name());
3856 move.addAnnotation(progAnnotation);
3857 foundLSU = true;
3858 }
3859 }
3860 }
3861
3862 /* Fail silently for now.
3863
3864 The problem here is that stack instructions should be mapped
3865 to AS0 but they do not have memoperands, thus
3866 addPointerAnnotations() does not manage to figure out any
3867 real address space info for it. Thus, we just could
3868 assume all such instructions belong to the default AS.
3869
3870 The problem appears with custom operations which take in
3871 memory operands. For example, TRY_LOCK_ADDR etc. of the DILU.
3872 The INLINEASM blocks, even if the operand is marked as 'm', do not
3873 produce MachineInstrs with memoperands, thus the pointer info cannot
3874 be obtained. However, in that case the address space could be
3875 something else than the default.
3876
3877 For now, we leave the AS info out in case FU with the operation and
3878 the address space is found, thus assume there is only one such FU
3879 which is then selected correctly during the scheduling.
3880 We only abort if the asNum != 0, otherwise fail silently.
3881 */
3882 if (!foundLSU) {
3883 if (asNum == 0){
3884#ifdef WARN_AS_FU_NOT_FOUND
3885 if (true || Application::verboseLevel() > 0) {
3887 << "WARNING: no candidate FU found for "
3888 << move.toString() << " with address space id "
3889 << asNum << " not adding any AS info."
3890 << std::endl;
3891 }
3892#endif
3893 } else {
3894 // If the asNum isn't already 0, we can't quietly make the
3895 // assumption that it should be 0. Instead abort.
3896 abortWithError((boost::format("ERROR: No candidate FU found for %s"
3897 " address space id %u") % move.toString() % asNum).str());
3898 }
3899 }
3900}
#define abortWithError(message)
static int verboseLevel()
static std::ostream & logStream()
virtual bool hasNumericalId(unsigned id) const
virtual AddressSpace * addressSpace() const
virtual bool hasOperation(const std::string &name) const
virtual bool hasAddressSpace() const
ComponentType * item(int index) const
virtual FunctionUnitNavigator functionUnitNavigator() const
Definition Machine.cc:380
void addAnnotation(const ProgramAnnotation &annotation)
std::string toString() const
Definition Move.cc:436
Terminal & source() const
Definition Move.cc:302
Terminal & destination() const
Definition Move.cc:323
virtual bool isFUPort() const
Definition Terminal.cc:118

References abortWithError, TTAProgram::AnnotatedInstructionElement::addAnnotation(), TTAMachine::FunctionUnit::addressSpace(), TTAMachine::Machine::Navigator< ComponentType >::count(), TTAProgram::Move::destination(), TTAMachine::Machine::functionUnitNavigator(), TTAMachine::FunctionUnit::hasAddressSpace(), TTAMachine::AddressSpace::hasNumericalId(), TTAMachine::FunctionUnit::hasOperation(), TTAProgram::Terminal::isFUPort(), TTAMachine::Machine::Navigator< ComponentType >::item(), Application::logStream(), mach_, TTAMachine::Component::name(), TTAProgram::Move::source(), TTAProgram::Move::toString(), and Application::verboseLevel().

Referenced by addPointerAnnotations().

Here is the call graph for this function:

◆ addLabelForProgramOperation()

void llvm::LLVMTCEBuilder::addLabelForProgramOperation ( TCEString  label,
ProgramOperationPtr  po 
)
inlineprotected

Definition at line 222 of file LLVMTCEBuilder.hh.

223 {
224 labeledPOs_[label] = po;
225 }
std::map< TCEString, ProgramOperationPtr > labeledPOs_

References labeledPOs_.

Referenced by llvm::LLVMTCEIRBuilder::buildTCECFG().

◆ addPointerAnnotations()

void LLVMTCEBuilder::addPointerAnnotations ( const llvm::MachineInstr *  mi,
TTAProgram::Move move 
)
private

Adds annotations to a pointer-register move to assist the TCE-side alias analysis.

Note: this function now assumes that mi has only one address operand.

TODO: this is not very optimal, it gets the offset info only for the memory accesses to function argument pointers?

FIXME: this is not correct, especially when the above offset info is set!

Definition at line 1827 of file LLVMTCEBuilder.cc.

1828 {
1829
1830 // copy some pointer data to Move annotations
1831#if 0
1832 if (mi->memoperands_begin() == mi->memoperands_end()) {
1833 Application::logStream() << "move " << move->toString()
1834 << " does not have mem operands!"
1835 << std::endl;
1836 }
1837#endif
1838
1839 if (pregions_->markersFound()) {
1840 unsigned nodeId = pregions_->pregion(*mi);
1841 if (nodeId != UINT_MAX) {
1842 TTAProgram::ProgramAnnotation progAnnotation(
1844 nodeId);
1845 move.addAnnotation(progAnnotation);
1846 }
1847 }
1848
1849 int addrSpaceId = 0;
1850 // TODO: why this is a loop actually?? It only handles a single
1851 // Move anyways --Pekka
1852 for (MachineInstr::mmo_iterator i = mi->memoperands_begin();
1853 i != mi->memoperands_end(); i++) {
1854
1855 const PseudoSourceValue* psv = (*i)->getPseudoValue();
1856 if (psv != NULL) {
1857 if (psv->isConstant(curFrameInfo_)) {
1858 TTAProgram::ProgramAnnotation progAnnotation(
1860 move.addAnnotation(progAnnotation);
1861 } else {
1862// it seems this breaks something, so disabled.
1863#if 0
1864 if (!psv->isAliased(curFrameInfo_)) {
1865 TTAProgram::ProgramAnnotation progAnnotation(
1867 move.addAnnotation(progAnnotation);
1868 }
1869#endif
1870 }
1871 }
1872 const llvm::Value* memOpValue = (*i)->getValue();
1873
1874 if (memOpValue != NULL) {
1875 std::string pointerName = "";
1876 // can we get the name right away or have to through
1877 // GetElemntPtrInst
1878
1879 if (memOpValue->hasName()) {
1880 pointerName = memOpValue->getName().str();
1881 } else if (isa<GetElementPtrInst>(memOpValue)) {
1882 memOpValue =
1883 cast<GetElementPtrInst>(
1884 memOpValue)->getPointerOperand();
1885 if (memOpValue->hasName()) {
1886 pointerName = memOpValue->getName().str();
1887 }
1888 }
1889
1890 /// TODO: this is not very optimal, it gets the offset
1891 /// info only for the memory accesses to function argument
1892 /// pointers?
1893 if (pointerName.length() > 0 &&
1894 isa<Argument>(memOpValue)) {
1895 unsigned offset;
1896 offset = (*i)->getOffset();
1897 TTAProgram::ProgramAnnotation progAnnotation(
1899 offset);
1900 move.addAnnotation(progAnnotation);
1901 }
1902
1903 // try to find the origin for the pointer which can be
1904 // a function argument with 'noalias' attribute set
1905 const llvm::Value* originMemOpValue = memOpValue;
1906 while (originMemOpValue != NULL) {
1907 TCEString currentPointerName =
1908 (std::string)originMemOpValue->getName();
1909
1910 // Query metadata of the memory operands to find work item
1911 // identifiers for OpenCL memory operands.
1912 if (dyn_cast<Instruction>(originMemOpValue) &&
1913 dyn_cast<Instruction>(originMemOpValue)->getMetadata("wi")) {
1914 const MDNode* md =
1915 cast<Instruction>(originMemOpValue)->getMetadata("wi");
1916 const MDNode* XYZ = dyn_cast<MDNode>(md->getOperand(2));
1917 assert(XYZ->getNumOperands() == 4);
1918 ConstantInt *CX = dyn_cast<ConstantInt>(
1919 dyn_cast<llvm::ConstantAsMetadata>(XYZ->getOperand(1))->getValue());
1920 ConstantInt *CY = dyn_cast<ConstantInt>(
1921 dyn_cast<llvm::ConstantAsMetadata>(XYZ->getOperand(2))->getValue());
1922 ConstantInt *CZ = dyn_cast<ConstantInt>(
1923 dyn_cast<llvm::ConstantAsMetadata>(XYZ->getOperand(3))->getValue());
1924
1925 int id = (CZ->getZExtValue() & 0x0FF)
1926 | ((CY->getZExtValue() & 0x0FF) << 8)
1927 | ((CX->getZExtValue() & 0x0FF) << 16);
1928 TTAProgram::ProgramAnnotation progAnnotation(
1930 ANN_OPENCL_WORK_ITEM_ID, id);
1931 move.addAnnotation(progAnnotation);
1932 // In case the memory operand is BitCastInst, we may be
1933 // looking at the vector memory access.
1934 // Find the type of the accessed element and if it is
1935 // vector add second annotation marking the last work
1936 // it id the vector is accessing.
1937 // Without this information there DDGBuilder can not
1938 // correctly create edges.
1939 if (isa<BitCastInst>(originMemOpValue)) {
1940 llvm::Type* type =
1941 dyn_cast<BitCastInst>(originMemOpValue)->getDestTy();
1942 if (type->isPointerTy()) {
1943 #ifdef LLVM_OLDER_THAN_15
1944 llvm::Type* typeElem =
1945 cast<PointerType>(type)->getElementType();
1946 #else
1947 //TODO: Replace this with getLoadStoreType but
1948 // it takes a non const argument?
1949 assert((isa<LoadInst>(originMemOpValue)
1950 || isa<StoreInst>(originMemOpValue)) &&
1951 "Expected Load or Store instruction");
1952 llvm::Type* typeElem = NULL;
1953 if (auto *LI = dyn_cast<LoadInst>(originMemOpValue))
1954 typeElem = LI->getType();
1955 else
1956 typeElem = cast<StoreInst>(originMemOpValue)
1957 ->getValueOperand()->getType();
1958 #endif
1959 if (typeElem->isVectorTy()) {
1960 int numElems = cast<VectorType>(typeElem)
1961 ->getElementCount()
1962 .getKnownMinValue();
1963 int idLast = (CZ->getZExtValue() & 0x0FF)
1964 | ((CY->getZExtValue() & 0x0FF) << 8)
1965 | (((CX->getZExtValue()
1966 + numElems) & 0x0FF) << 16);
1967 TTAProgram::ProgramAnnotation progAnnotation(
1969 ANN_OPENCL_WORK_ITEM_ID_LAST, idLast);
1970 move.addAnnotation(progAnnotation);
1971 }
1972 }
1973 }
1974 }
1975
1976 if (isa<Argument>(originMemOpValue) &&
1977 cast<Argument>(originMemOpValue)->hasNoAliasAttr()) {
1978 TTAProgram::ProgramAnnotation progAnnotation(
1980 ANN_POINTER_NOALIAS, 1);
1981 move.addAnnotation(progAnnotation);
1982 noAliasFound_ = true;
1983
1984
1985 /// FIXME: this is not correct, especially
1986 /// when the above offset info is set!
1987
1988 /*
1989 As the restrict keyword is assigned only to the pointer
1990 we found, we now pretend we are accessing through
1991 that pointer even though we might not be as the
1992 new pointer might be created through pointer
1993 arithmetic. In case
1994 we are not, the offset in the pointer arithmetic
1995 should be associated with the real pointer, not
1996 the origin pointer with the restrict keyword!
1997
1998 Correct way is to add another annotation from
1999 which restrict pointer the current pointer is
2000 derived from and separate annotation for the
2001 real pointer name + offset.
2002 */
2003 pointerName = originMemOpValue->getName().str();
2004 break;
2005 } else if (isa<GetElementPtrInst>(originMemOpValue)) {
2006 originMemOpValue =
2007 cast<GetElementPtrInst>(originMemOpValue)->
2008 getPointerOperand();
2009 } else if (isa<BitCastInst>(originMemOpValue)) {
2010 originMemOpValue =
2011 cast<BitCastInst>(originMemOpValue)->
2012 getOperand(0);
2013 } else if (isa<PtrToIntInst>(originMemOpValue)) {
2014 originMemOpValue =
2015 cast<PtrToIntInst>(originMemOpValue)->
2016 getOperand(0);
2017 } else {
2018 break;
2019 }
2020 }
2021
2022 if (pointerName != "") {
2025 pointerName);
2026 move.addAnnotation(pointerAnn);
2027 }
2028
2029 addrSpaceId =
2030 cast<PointerType>(memOpValue->getType())->
2031 getAddressSpace();
2032
2033 if (addrSpaceId != 0) {
2034 // this annotation is used only for alias analysis as
2035 // the address spaces are assumed to be always disjoint
2036 std::string addressSpace =
2037 (boost::format("%d") % addrSpaceId).str();
2038 TTAProgram::ProgramAnnotation progAnnotation(
2040 addressSpace);
2041 move.addAnnotation(progAnnotation);
2042 multiAddrSpacesFound_ = true;
2043 }
2044 }
2045 }
2047 // annotate all memory moves with FU candidate sets
2048 // so the memory operations are assigned to the correct
2049 // load-store units in the multimemory machine
2050
2051 // for stack accesses, there is no LLVM pointer info in which
2052 // case we add the default addr space id 0
2053 addCandidateLSUAnnotations(addrSpaceId, move);
2054 }
2055}
#define assert(condition)
unsigned pregion(const llvm::MachineInstr &I) const
@ ANN_POINTER_NAME
information retrieved (from LLVM) about a pointer access
@ ANN_PARALLEL_REGION_ID
The ID from the _TCEPREGION_START(N) markers.
@ ANN_CONSTANT_MEM
Constant memory access.
MachineFrameInfo * curFrameInfo_
void addCandidateLSUAnnotations(unsigned asNum, TTAProgram::Move &move)
bool multiDataMemMachine_
Set to true in case this machine has more than one data address spaces.
bool noAliasFound_
set to true in case at least one 'noalias' attribute (from the use of 'restricted' pointers) has been...
PRegionMarkerAnalyzer * pregions_
bool multiAddrSpacesFound_
set to true in case at least one non-default address space memory access has been found in the genera...

References TTAProgram::AnnotatedInstructionElement::addAnnotation(), addCandidateLSUAnnotations(), TTAProgram::ProgramAnnotation::ANN_CONSTANT_MEM, TTAProgram::ProgramAnnotation::ANN_PARALLEL_REGION_ID, TTAProgram::ProgramAnnotation::ANN_POINTER_ADDR_SPACE, TTAProgram::ProgramAnnotation::ANN_POINTER_NAME, TTAProgram::ProgramAnnotation::ANN_POINTER_OFFSET, TTAProgram::ProgramAnnotation::ANN_STACKUSE_SPILL, assert, curFrameInfo_, Application::logStream(), PRegionMarkerAnalyzer::markersFound(), multiAddrSpacesFound_, multiDataMemMachine_, noAliasFound_, PRegionMarkerAnalyzer::pregion(), pregions_, and TTAProgram::Move::toString().

Referenced by emitInstruction(), and emitOperationMacro().

Here is the call graph for this function:

◆ addressSpaceById()

TTAMachine::AddressSpace & LLVMTCEBuilder::addressSpaceById ( unsigned  id)
private

Definition at line 3769 of file LLVMTCEBuilder.cc.

3769 {
3770
3773
3776 for (int i = 0; i < asNav.count(); i++) {
3777 TTAMachine::AddressSpace& aSpace = *asNav.item(i);
3778 if (aSpace.hasNumericalId(id))
3779 return aSpace;
3780 }
3782 << "Address space with numerical id " << id << " not found."
3783 << std::endl;
3784 abort();
3785}
virtual AddressSpaceNavigator addressSpaceNavigator() const
Definition Machine.cc:392
TTAMachine::AddressSpace * defaultDataAddressSpace_
The default data memory address space (address space 0).

References TTAMachine::Machine::addressSpaceNavigator(), TTAMachine::Machine::Navigator< ComponentType >::count(), defaultDataAddressSpace_, TTAMachine::AddressSpace::hasNumericalId(), TTAMachine::Machine::Navigator< ComponentType >::item(), Application::logStream(), mach_, and multiDataMemMachine_.

Referenced by createDataDefinition(), createFPDataDefinition(), createGlobalValueDataDefinition(), createIntDataDefinition(), createTerminal(), doFinalization(), emitConstantPool(), emitDataDef(), emitSPInitialization(), initDataSections(), and padToAlignment().

Here is the call graph for this function:

◆ addressSpaceId()

unsigned llvm::LLVMTCEBuilder::addressSpaceId ( TTAMachine::AddressSpace aSpace) const
private

◆ clearFunctionBookkeeping()

void llvm::LLVMTCEBuilder::clearFunctionBookkeeping ( )
inlineprotected

Definition at line 231 of file LLVMTCEBuilder.hh.

231 {
232 labeledPOs_.clear();
233 symbolicPORefs_.clear();
234 }
std::set< TTAProgram::TerminalProgramOperation * > symbolicPORefs_

References labeledPOs_, and symbolicPORefs_.

Referenced by llvm::LLVMTCEIRBuilder::writeMachineFunction().

◆ copyFUAnnotations()

void LLVMTCEBuilder::copyFUAnnotations ( const std::vector< TTAProgram::Instruction * > &  operandMoves,
TTAProgram::Move move 
) const
private

Definition at line 1801 of file LLVMTCEBuilder.cc.

1803 {
1804 for (unsigned int i = 0; i < operandMoves.size(); i++) {
1805 TTAProgram::Move& operandMove = operandMoves[i]->move(0);
1806 for (int j = 0; j < operandMove.annotationCount(); j++) {
1807 TTAProgram::ProgramAnnotation anno = operandMove.annotation(j);
1808 if (anno.id() ==
1810 move.addAnnotation(
1813 anno.payload()));
1814 }
1815 }
1816 }
1817}
int annotationCount(ProgramAnnotation::Id id=ProgramAnnotation::ANN_UNDEF_ID) const
ProgramAnnotation annotation(int index, ProgramAnnotation::Id id=ProgramAnnotation::ANN_UNDEF_ID) const
const std::vector< Byte > & payload() const
ProgramAnnotation::Id id() const
@ ANN_ALLOWED_UNIT_DST
Dst. unit candidate.
@ ANN_ALLOWED_UNIT_SRC
Candidate units can be passed for resource manager for choosing the source/destination unit of the mo...

References TTAProgram::AnnotatedInstructionElement::addAnnotation(), TTAProgram::ProgramAnnotation::ANN_ALLOWED_UNIT_DST, TTAProgram::ProgramAnnotation::ANN_ALLOWED_UNIT_SRC, TTAProgram::AnnotatedInstructionElement::annotation(), TTAProgram::AnnotatedInstructionElement::annotationCount(), TTAProgram::ProgramAnnotation::id(), and TTAProgram::ProgramAnnotation::payload().

Referenced by emitInstruction().

Here is the call graph for this function:

◆ createAddrTerminal()

TTAProgram::Terminal * llvm::LLVMTCEBuilder::createAddrTerminal ( const MachineOperand &  base,
const MachineOperand &  offset 
)
private

◆ createDataDefinition()

unsigned LLVMTCEBuilder::createDataDefinition ( int  addressSpaceId,
unsigned &  addr,
const Constant *  cv,
bool  forceInitialize = false,
unsigned  forceAlignment = 0 
)
private

Creates POM data definition from a llvm data initializer.

Parameters
addrAddress for the POM data.
cvInitializer for the data in llvm.
forceInitializeIn case wanting to use initialization data even for null values.
forceAlignmentUse the given alignment for the constant instead of the alignment defined in DataLayout.
Returns
POM data address after padding data to correct alignment.

Definition at line 523 of file LLVMTCEBuilder.cc.

525 {
526
527 unsigned sz = dl_->getTypeStoreSize(cv->getType());
528 llvm::Align align = (forceAlignment == 0)?
529 dl_->getABITypeAlign(cv->getType()):llvm::Align(forceAlignment);
530
531 // KLUDGE FIX: Currently, for little-endian machines, OSAL base simd
532 // module has only vector load and store operations that require full
533 // vector width alignment.
534 // Remove this when accesses can be done at ABI alignment.
535 if (mach_->isLittleEndian() && cv->getType()->isVectorTy()) {
536 align = (forceAlignment == 0)?llvm::Align(sz):llvm::Align(forceAlignment);
537 }
538
539 TTAMachine::AddressSpace& aSpace =
542
543 padToAlignment(addressSpaceId, addr, align.value());
544
545 // paddedAddr is the actual address data was put to
546 // after alignment.
547 unsigned paddedAddr = addr;
548
549 // Initialize with zeros if this is an uninitialized part of a partially
550 // initialized data structure.
551 if (!forceInitialize &&
552 (cv->isNullValue() || dyn_cast<UndefValue>(cv) != NULL)) {
553 TTAProgram::Address address(addr, aSpace);
556 address, sz, mach_->isLittleEndian(), NULL, true));
557 addr += sz;
558 return paddedAddr;
559 }
560
561 if (isa<ConstantArray>(cv) ||
562 isa<ConstantStruct>(cv) ||
563 isa<ConstantVector>(cv)) {
564
565 for (unsigned i = 0, e = cv->getNumOperands(); i != e; ++i) {
567 addressSpaceId, addr, cast<Constant>(cv->getOperand(i)));
568 }
569 } else if (const ConstantInt* ci = dyn_cast<ConstantInt>(cv)) {
571 } else if (const ConstantFP* cfp = dyn_cast<ConstantFP>(cv)) {
573 } else if (const GlobalValue* gv = dyn_cast<GlobalValue>(cv)) {
575 } else if (const ConstantExpr* ce = dyn_cast<ConstantExpr>(cv)) {
577 } else if (const ConstantDataArray* cda = dyn_cast<ConstantDataArray>(cv)){
578 if (cda->isNullValue()) {
579 TTAProgram::Address address(addr, aSpace);
580 dmem.addDataDefinition(
582 address, sz, mach_->isLittleEndian(), NULL, false) );
583 } else {
584 /* If the array has non-zero values, do not split the
585 definitions to initialized and uninitialized data sections, but
586 initialize them all. Otherwise we might end up having zillions
587 of UData and Data sections after each other in the TPEF for the
588 initialization data, because the sections have only one start
589 address. It soon exceeds the maximum number of
590 sections in case of large initialized arrays with some of the
591 values being zeros. */
592 bool allZeros = true;
593 for (unsigned i = 0, e = cda->getNumElements(); i != e; ++i) {
594 llvm::Constant *ace =
595 cast<Constant>(cda->getElementAsConstant(i));
596 if (ace->isNullValue() || isa<UndefValue>(ace))
597 continue;
598 allZeros = false;
599 break;
600 }
601
602 for (unsigned int i = 0; i < cda->getNumElements(); i++) {
604 addressSpaceId, addr, cda->getElementAsConstant(i),
605 !allZeros);
606 }
607 }
608 } else if (const ConstantDataSequential* cds =
609 dyn_cast<ConstantDataSequential>(cv)) {
610 // Force other alignment for vector types. If the element type is less
611 // than i32, it gets promoted based on DataLayout's ABI or Preferred
612 // alignment of integer type.
613 unsigned alignmentOverride = 0;
614 if (cv->getType()->isVectorTy()) {
615 alignmentOverride = sz/cds->getNumElements();
616 }
617 for (unsigned int i = 0; i < cds->getNumElements(); i++) {
619 addressSpaceId, addr, cds->getElementAsConstant(i),
620 forceInitialize, alignmentOverride);
621 }
622 } else {
623 // LLVM does not include dump() when built in non-debug mode.
624 // cv->dump();
625 abortWithError("Unknown cv type.");
626 }
627 return paddedAddr;
628}
bool isLittleEndian() const
Definition Machine.hh:258
void addDataDefinition(DataDefinition *dataDef)
Definition DataMemory.cc:66
unsigned createDataDefinition(int addressSpaceId, unsigned &addr, const Constant *cv, bool forceInitialize=false, unsigned forceAlignment=0)
TTAProgram::DataMemory & dataMemoryForAddressSpace(TTAMachine::AddressSpace &aSpace)
TTAMachine::AddressSpace & addressSpaceById(unsigned id)
void createExprDataDefinition(int addressSpaceId, unsigned &addr, const ConstantExpr *gv, int offset=0)
unsigned addressSpaceId(TTAMachine::AddressSpace &aSpace) const
void createFPDataDefinition(int addressSpaceId, unsigned &addr, const llvm::ConstantFP *cfp)
void createGlobalValueDataDefinition(int addressSpaceId, unsigned &addr, const GlobalValue *gv, int offset=0)
void createIntDataDefinition(int addressSpaceId, unsigned &addr, const llvm::ConstantInt *ci, bool isPointer=false)
void padToAlignment(int addressSpaceId, unsigned &addr, unsigned align)

References abortWithError, TTAProgram::DataMemory::addDataDefinition(), addressSpaceById(), addressSpaceId(), createDataDefinition(), createExprDataDefinition(), createFPDataDefinition(), createGlobalValueDataDefinition(), createIntDataDefinition(), dataMemoryForAddressSpace(), dl_, TTAMachine::Machine::isLittleEndian(), mach_, and padToAlignment().

Referenced by createDataDefinition(), createExprDataDefinition(), emitDataDef(), and emitDataDef().

Here is the call graph for this function:

◆ createExprDataDefinition()

void LLVMTCEBuilder::createExprDataDefinition ( int  addressSpaceId,
unsigned &  addr,
const ConstantExpr *  ce,
int  offset = 0 
)
private

Creates POM data definition from a llvm constant expression initializer.

Parameters
addrAddress of the POM data definition.
ceExpression to create the data definition for.
offsetOffset for an address defined by the expression.

Definition at line 840 of file LLVMTCEBuilder.cc.

841 {
842
843 assert(addr % (dl_->getABITypeAlign(ce->getType()).value()) == 0 &&
844 "Invalid alignment for constant expr!");
845
846 unsigned opcode = ce->getOpcode();
847 if (opcode == Instruction::GetElementPtr) {
848 const Constant* ptr = ce->getOperand(0);
849 SmallVector<Value*, 8> idxVec(ce->op_begin() + 1, ce->op_end());
850
851 APInt offsetAI(dl_->getPointerTypeSizeInBits(ce->getType()), 0);
852 bool success = cast<GEPOperator>(ce)->accumulateConstantOffset(
853 *dl_, offsetAI);
854 assert(success); // Fails if GEP is not all-constant.
855 int64_t ptrOffset = offset + offsetAI.getSExtValue();
856
857 if (const GlobalValue* gv = dyn_cast<GlobalValue>(ptr)) {
859 addressSpaceId, addr, gv, ptrOffset);
860 } else if (const ConstantExpr* ce =
861 dyn_cast<ConstantExpr>(ptr)) {
863 addressSpaceId, addr, ce, ptrOffset);
864 } else {
865 assert(false && "Unsuported getElementPtr target!");
866 }
867 } else if (opcode == Instruction::BitCast) {
868 const Constant* ptr = ce->getOperand(0);
869 if (const ConstantExpr* ce = dyn_cast<ConstantExpr>(ptr)) {
871 addressSpaceId, addr, ce, offset);
872 } else if (const GlobalValue* gv = dyn_cast<GlobalValue>(ptr)) {
874 addressSpaceId, addr, gv, offset);
875 } else {
876 assert(offset == 0);
877#ifndef NDEBUG
878 unsigned dataAddr =
880 addressSpaceId, addr, ptr);
881 // Data should have been padded already:
882 assert(dataAddr == addr);
883#else
885#endif
886 }
887 } else if (opcode == Instruction::IntToPtr) {
888 assert(offset == 0);
889 const ConstantInt* ci = dyn_cast<ConstantInt>(ce->getOperand(0));
890 assert(ci != NULL);
892 } else if (opcode == Instruction::PtrToInt) {
893 assert(offset == 0);
894 // Data should have been padded already:
895#ifndef NDEBUG
896 unsigned dataAddr =
897#endif
898 createDataDefinition(addressSpaceId, addr, ce->getOperand(0));
899 assert(dataAddr == addr);
900 } else if (opcode == Instruction::Add) {
901 assert(false && "NOT IMPLEMENTED");
902 } else if (opcode == Instruction::Sub) {
903 assert(false && "NOT IMPLEMENTED");
904 } else {
905 assert(false && "NOT IMPLEMENTED");
906 }
907}

References addressSpaceId(), assert, createDataDefinition(), createExprDataDefinition(), createGlobalValueDataDefinition(), createIntDataDefinition(), and dl_.

Referenced by createDataDefinition(), and createExprDataDefinition().

Here is the call graph for this function:

◆ createFPDataDefinition()

void LLVMTCEBuilder::createFPDataDefinition ( int  addressSpaceId,
unsigned &  addr,
const llvm::ConstantFP *  cfp 
)
private

Creates data definition of a floating point constant.

Definition at line 694 of file LLVMTCEBuilder.cc.

695 {
696
697 assert(addr % (dl_->getABITypeAlign(cfp->getType()).value()) == 0
698 && "Invalid alignment for constant fp!");
699
700 TTAMachine::AddressSpace& aSpace =
703
704 TTAProgram::Address start(addr, aSpace);
705 std::vector<MinimumAddressableUnit> maus;
706
707 TYPE_CONST Type* type = cfp->getType();
708 unsigned sz = dl_->getTypeStoreSize(type);
709
710 TTAProgram::DataDefinition* def = NULL;
711
712 if (type->getTypeID() == Type::DoubleTyID) {
713
714 double val = cfp->getValueAPF().convertToDouble();
715 assert(sz == 8);
716 union {
717 double d;
718 char bytes[8];
719 } u;
720
721 u.d = val;
722 if (!mach_->isLittleEndian()) {
723 for (unsigned i = 0; i < sz; i++) {
724 maus.push_back(u.bytes[sz - i - 1]);
725 }
726 } else {
727 for (unsigned i = 0; i < sz; i++) {
728 maus.push_back(u.bytes[i]);
729 }
730 }
732 start, maus, mach_->isLittleEndian());
733 } else if (type->getTypeID() == Type::FloatTyID) {
734
735 float val = cfp->getValueAPF().convertToFloat();
736 assert(sz == 4);
737 union {
738 float f;
739 char bytes[4];
740 } u;
741
742 u.f = val;
743 if (!mach_->isLittleEndian()) {
744 for (unsigned i = 0; i < sz; i++) {
745 maus.push_back(u.bytes[sz - i - 1]);
746 }
747 } else {
748 for (unsigned i = 0; i < sz; i++) {
749 maus.push_back(u.bytes[i]);
750 }
751 }
753 start, maus, mach_->isLittleEndian());
754 } else if (type->getTypeID() == Type::HalfTyID) {
755 APInt bits = cfp->getValueAPF().bitcastToAPInt();
756 uint64_t bigval = bits.getLimitedValue(0xFFFF);
757 assert(sz == 2);
758 union {
759 short h;
760 char bytes[2];
761 } u;
762 u.h = bigval;
763 if (!mach_->isLittleEndian()) {
764 for (unsigned i = 0; i < sz; i++) {
765 maus.push_back(u.bytes[sz - i - 1]);
766 }
767 } else {
768 for (unsigned i = 0; i < sz; i++) {
769 maus.push_back(u.bytes[i]);
770 }
771 }
773 start, maus, mach_->isLittleEndian());
774 } else {
775 assert(false && "Unknown floating point typeID!");
776 }
777 addr += def->size();
778 dmem.addDataDefinition(def);
779}
#define TYPE_CONST

References TTAProgram::DataMemory::addDataDefinition(), addressSpaceById(), addressSpaceId(), assert, dataMemoryForAddressSpace(), dl_, TTAMachine::Machine::isLittleEndian(), mach_, TTAProgram::DataDefinition::size(), and TYPE_CONST.

Referenced by createDataDefinition().

Here is the call graph for this function:

◆ createFUTerminal()

virtual TTAProgram::Terminal * llvm::LLVMTCEBuilder::createFUTerminal ( const MachineOperand &  ) const
inlineprotectedvirtual

Reimplemented in llvm::LLVMPOMBuilder, llvm::LLVMTCEIRBuilder, and llvm::LLVMTCEPOMBuilder.

Definition at line 171 of file LLVMTCEBuilder.hh.

172 {
173 return NULL;
174 }

Referenced by createTerminal().

◆ createGlobalValueDataDefinition()

void LLVMTCEBuilder::createGlobalValueDataDefinition ( int  addressSpaceId,
unsigned &  addr,
const GlobalValue *  gv,
int  offset = 0 
)
private

Creates data definition for a global value reference.

Parameters
addrAddress where the reference is to be defined.
gvGlobal value reference.

Definition at line 789 of file LLVMTCEBuilder.cc.

790 {
791
792 TYPE_CONST PointerType* type = gv->getType();
793
794 unsigned sz = dl_->getTypeStoreSize(type);
795
796 SmallString<256> Buffer;
797 mang_->getNameWithPrefix(Buffer, gv, false);
798 TCEString label(Buffer.c_str());
799
800 TTAMachine::AddressSpace& aSpace =
803
804 TTAProgram::Address start(addr, aSpace);
805
806 TTAProgram::DataDefinition* def = NULL;
807 if (codeLabels_.find(label) != codeLabels_.end()) {
808 assert(
809 offset == 0 &&
810 "Instruction reference with an offset not supported yet.");
811
812 TTAProgram::Instruction* instr = codeLabels_[label];
815
817 start, sz, ref, mach_->isLittleEndian());
818 } else if (dataLabels_.find(label) != dataLabels_.end()) {
819 unsigned gvAS = type->getAddressSpace();
821 TTAProgram::Address ref((dataLabels_[label] + offset), aSpace);
822
824 start, sz, ref, mach_->isLittleEndian());
825 } else {
826 assert(false && "Global value label not found!");
827 }
828 addr += def->size();
829 dmem.addDataDefinition(def);
830}
InstructionReference createReference(Instruction &ins)
InstructionReferenceManager & instructionReferenceManager() const
Definition Program.cc:688
std::map< std::string, unsigned > dataLabels_
Data labels.
TTAProgram::Program * prog_
Current program being built.
std::map< std::string, TTAProgram::Instruction * > codeLabels_
Code labels.

References TTAProgram::DataMemory::addDataDefinition(), addressSpaceById(), addressSpaceId(), assert, codeLabels_, TTAProgram::InstructionReferenceManager::createReference(), dataLabels_, dataMemoryForAddressSpace(), dl_, TTAProgram::Program::instructionReferenceManager(), TTAMachine::Machine::isLittleEndian(), mach_, mang_, prog_, TTAProgram::DataDefinition::size(), and TYPE_CONST.

Referenced by createDataDefinition(), and createExprDataDefinition().

Here is the call graph for this function:

◆ createGuard()

TTAProgram::MoveGuard * LLVMTCEBuilder::createGuard ( const TTAProgram::Terminal terminal,
bool  trueOrFalse 
)
private

Creates a register guard to given guard register.

Definition at line 3724 of file LLVMTCEBuilder.cc.

3725 {
3726 const TTAProgram::TerminalRegister* guardReg =
3727 dynamic_cast<const TTAProgram::TerminalRegister*>(terminal);
3728 if (guardReg == NULL) {
3729 return NULL;
3730 }
3731
3732 bool hasPortGuard = false;
3734 for (int i = 0; i < busNav.count(); i++) {
3735 Bus* bus = busNav.item(i);
3736 for (int i = 0; i < bus->guardCount(); i++) {
3737 RegisterGuard* regGuard = dynamic_cast<RegisterGuard*>(
3738 bus->guard(i));
3739 if (regGuard != NULL &&
3740 regGuard->registerFile() == &guardReg->registerFile() &&
3741 regGuard->registerIndex() == (int)guardReg->index() &&
3742 regGuard->isInverted() != trueOrFalse) {
3743 return new TTAProgram::MoveGuard(*regGuard);
3744 }
3745 PortGuard* portGuard = dynamic_cast<PortGuard*>(
3746 bus->guard(i));
3747 if (portGuard != nullptr &&
3748 portGuard->isInverted() != trueOrFalse)
3749 hasPortGuard = true;
3750 }
3751 }
3752
3753 if (hasPortGuard) {
3754 RegisterGuard* bypassRegGuard =
3755 new RegisterGuard(!trueOrFalse, guardReg->registerFile(),
3756 guardReg->index(), nullptr);
3757
3758 return new TTAProgram::MoveGuard(*bypassRegGuard);
3759 } else {
3760 std::cerr << "Warning: Could not find suitable guard from any bus in the "
3761 << "processor. Did you forget to add guards to the processor?"
3762 << std::endl;
3763 return NULL;
3764 }
3765}
Guard * guard(int index) const
Definition Bus.cc:456
int guardCount() const
Definition Bus.cc:441
virtual bool isInverted() const
virtual BusNavigator busNavigator() const
Definition Machine.cc:356
const RegisterFile * registerFile() const
virtual int index() const
virtual const TTAMachine::RegisterFile & registerFile() const

References TTAMachine::Machine::busNavigator(), TTAMachine::Machine::Navigator< ComponentType >::count(), TTAMachine::Bus::guard(), TTAMachine::Bus::guardCount(), TTAProgram::TerminalRegister::index(), TTAMachine::Guard::isInverted(), TTAMachine::Machine::Navigator< ComponentType >::item(), mach_, TTAMachine::RegisterGuard::registerFile(), TTAProgram::TerminalRegister::registerFile(), and TTAMachine::RegisterGuard::registerIndex().

Referenced by emitInstruction(), emitMove(), and emitSelect().

Here is the call graph for this function:

◆ createIntDataDefinition()

void LLVMTCEBuilder::createIntDataDefinition ( int  addressSpaceId,
unsigned &  addr,
const llvm::ConstantInt *  ci,
bool  isPointer = false 
)
private

Creates data definition of a constant integer value.

Parameters
addrAddress where the integer is to be defined.
ciConstant initializer for the integer value.

Definition at line 638 of file LLVMTCEBuilder.cc.

640 {
641
642 assert(addr % (dl_->getABITypeAlign(ci->getType()).value()) == 0 &&
643 "Invalid alignment for constant int!");
644
645 std::vector<MinimumAddressableUnit> maus;
646
647 unsigned sz = ((ci->getBitWidth() + MAU_BITS-1) / MAU_BITS);
648
649 if (isPointer) {
651 }
652
653 if (!(sz == 1 || sz == 2 || sz == 4 || sz == 8)) {
654
655// std::cerr << "## int with size " << sz << "!" << std::endl;
656 }
657
658 TTAMachine::AddressSpace& aSpace =
661
662 TTAProgram::Address start(addr, aSpace);
663
664 // FIXME: Assuming 8bit MAU.
665 union {
666 int64_t d;
667 char bytes[8];
668 } u;
669
670 u.d = ci->getZExtValue();
671
673
674 if (!mach_->isLittleEndian()) {
675 for (unsigned i = 0; i < sz; i++) {
676 maus.push_back(u.bytes[sz - i - 1]);
677 }
678 } else {
679 for (unsigned i = 0; i < sz; i++) {
680 maus.push_back(u.bytes[i]);
681 }
682 }
683
684 def = new TTAProgram::DataDefinition(start, maus, mach_->isLittleEndian());
685 addr += def->size();
686 dmem.addDataDefinition(def);
687}
bool is64bit() const
Definition Machine.hh:260
static unsigned POINTER_SIZE_64
static unsigned MAU_BITS
Target architechture MAU size in bits.
static unsigned POINTER_SIZE_32
Target architecture pointer size in maus.

References TTAProgram::DataMemory::addDataDefinition(), addressSpaceById(), addressSpaceId(), assert, dataMemoryForAddressSpace(), dl_, TTAMachine::Machine::is64bit(), TTAMachine::Machine::isLittleEndian(), mach_, MAU_BITS, POINTER_SIZE_32, POINTER_SIZE_64, and TTAProgram::DataDefinition::size().

Referenced by createDataDefinition(), and createExprDataDefinition().

Here is the call graph for this function:

◆ createMBBReference()

TTAProgram::Terminal * LLVMTCEBuilder::createMBBReference ( const MachineOperand &  mo)
protectedvirtual

Reimplemented in llvm::LLVMTCEIRBuilder.

Definition at line 2292 of file LLVMTCEBuilder.cc.

2292 {
2294
2297 mbbReferences_[ref] = mbbName(*mo.getMBB());
2298 return ref;
2299}
SimValue dummy(32)
a dummy simvalue which is given for operands that are not bound
std::string mbbName(const MachineBasicBlock &mbb)
std::map< TTAProgram::TerminalInstructionAddress *, std::string > mbbReferences_
Dummy basic block references that have to be fixed after all basic blocks have been built.

References dummy, mbbName(), and mbbReferences_.

Referenced by createTerminal().

Here is the call graph for this function:

◆ createMove() [1/2]

std::shared_ptr< TTAProgram::Move > LLVMTCEBuilder::createMove ( const MachineOperand &  src,
const MachineOperand &  dst,
TTAProgram::MoveGuard guard 
)
protected

Creates POM instruction for a move.

Parameters
srcThe source operand.
dstThe dst operand.
Returns
POM Move.

Definition at line 2393 of file LLVMTCEBuilder.cc.

2395 {
2396 assert(!src.isReg() || src.isUse());
2397 assert(dst.isDef());
2398
2399 // eliminate register-to-itself moves
2400 if (dst.isReg() && src.isReg() && dst.getReg() == src.getReg()) {
2401 return NULL;
2402 }
2403
2405 TTAProgram::Terminal* dstTerm = createTerminal(dst);
2406 TTAProgram::Terminal* srcTerm =
2407 createTerminal(src, dstTerm->port().width());
2408
2409 auto move = createMove(srcTerm, dstTerm, bus, guard);
2410
2411 return move;
2412}
virtual int width() const =0
virtual const TTAMachine::Port & port() const
Definition Terminal.cc:378
static UniversalMachine & instance()
TTAMachine::Bus & universalBus() const
std::shared_ptr< TTAProgram::Move > createMove(const MachineOperand &src, const MachineOperand &dst, TTAProgram::MoveGuard *guard)
TTAProgram::Terminal * createTerminal(const MachineOperand &mo, int bitLimit=0)

References assert, createMove(), createTerminal(), UniversalMachine::instance(), TTAProgram::Terminal::port(), UniversalMachine::universalBus(), and TTAMachine::Port::width().

Referenced by createMove(), emitComparisonForBranch(), emitInstruction(), emitMove(), llvm::LLVMTCEPOMBuilder::emitMove(), emitOperationMacro(), emitRemaingingBrach(), emitReturn(), emitSelect(), and emitSPInitialization().

Here is the call graph for this function:

◆ createMove() [2/2]

std::shared_ptr< TTAProgram::Move > LLVMTCEBuilder::createMove ( TTAProgram::Terminal src,
TTAProgram::Terminal dst,
const TTAMachine::Bus bus,
TTAProgram::MoveGuard guard = NULL 
)
protected

Creates program object model move.

Parameters
srcSource terminal of the move.
dstDestination terminal of the move.
busBus utilized to do the move.
guardGuard object for the move or NULL if the move is not guarded.
Returns
Created move.

Definition at line 3678 of file LLVMTCEBuilder.cc.

3682 {
3683
3684 std::shared_ptr<TTAProgram::Move> move = nullptr;
3685
3686 bool endRef = false;
3687
3688 if (src == NULL) {
3689 // Create a dummy source Terminal so the move can be added to an
3690 // instruction.
3691 SimValue val(0, mach_->is64bit() ? 64 : 32);
3692 src = new TTAProgram::TerminalImmediate(val);
3693 endRef = true;
3694 }
3695
3696 if (guard == NULL) {
3697 move = std::make_shared<TTAProgram::Move>(src, dst, bus);
3698 } else {
3699 move = std::make_shared<TTAProgram::Move>(src, dst, bus, guard);
3700 }
3701
3702 if (endRef) {
3703 endReferences_.push_back(move);
3704 }
3705
3706 return move;
3707}
std::vector< std::shared_ptr< TTAProgram::Move > > endReferences_
Dummy references to the _end symbol.

References endReferences_, TTAMachine::Machine::is64bit(), and mach_.

Here is the call graph for this function:

◆ createMoveNode()

virtual void llvm::LLVMTCEBuilder::createMoveNode ( ProgramOperationPtr ,
std::shared_ptr< TTAProgram::Move m,
bool   
)
inlineprivatevirtual

◆ createProgramOperationReference()

TTAProgram::Terminal * LLVMTCEBuilder::createProgramOperationReference ( const MachineOperand &  mo)
protectedvirtual

Definition at line 2264 of file LLVMTCEBuilder.cc.

2265 {
2266 llvm::MCSymbol* symbol = mo.getMCSymbol();
2268 new TTAProgram::TerminalProgramOperation(symbol->getName().str());
2269 symbolicPORefs_.insert(term);
2270 return term;
2271}

References symbolicPORefs_.

Referenced by createTerminal().

◆ createSPInitLoad()

void LLVMTCEBuilder::createSPInitLoad ( TTAProgram::CodeSnippet target,
TTAProgram::Terminal src,
TTAProgram::Terminal dst 
)
private

Creates instruction(s) to load initial stack pointer value.

Definition at line 3658 of file LLVMTCEBuilder.cc.

3661 {
3662
3663 CodeGenerator codegen(*mach_);
3664 codegen.loadTerminal(target, &src, &dst);
3665}

References TTAProgram::CodeGenerator::loadTerminal(), and mach_.

Referenced by emitSPInitialization().

Here is the call graph for this function:

◆ createSymbolReference() [1/2]

TTAProgram::Terminal * LLVMTCEBuilder::createSymbolReference ( const MachineOperand &  mo)
protectedvirtual

NOTE: Hack to get code compiling even if llvm falsely makes libcalls to external functions even if they are found from currently lowered program.

http://llvm.org/bugs/show_bug.cgi?id=2673

Should be removed after fix is applied to llvm.. (maybe never...)

Definition at line 2302 of file LLVMTCEBuilder.cc.

2302 {
2303 //} else if (mo.isExternalSymbol()) {
2304
2305 /**
2306 * NOTE: Hack to get code compiling even if llvm falsely makes libcalls to
2307 * external functions even if they are found from currently lowered program.
2308 *
2309 * http://llvm.org/bugs/show_bug.cgi?id=2673
2310 *
2311 * Should be removed after fix is applied to llvm.. (maybe never...)
2312 */
2313 return createSymbolReference(mo.getSymbolName());
2314}
virtual TTAProgram::Terminal * createSymbolReference(const MachineOperand &mo)

References createSymbolReference().

Referenced by createSymbolReference(), and createTerminal().

Here is the call graph for this function:

◆ createSymbolReference() [2/2]

TTAProgram::Terminal * LLVMTCEBuilder::createSymbolReference ( const TCEString symbolName)
protectedvirtual

END OF HACK

Reimplemented in llvm::LLVMTCEIRBuilder.

Definition at line 2317 of file LLVMTCEBuilder.cc.

2317 {
2318 if (name == END_SYMBOL_NAME) {
2319 return NULL;
2320 }
2321
2324
2325
2328 *dummy);
2329
2330 codeLabelReferences_[ref] = name;
2331 return ref;
2332 /**
2333 * END OF HACK
2334 */
2335
2336}
#define END_SYMBOL_NAME
std::map< TTAProgram::TerminalInstructionAddress *, std::string > codeLabelReferences_
Dummy code label references that have to be fixed after all instrutions have been built.

References codeLabelReferences_, dummy, and END_SYMBOL_NAME.

◆ createTerminal()

TTAProgram::Terminal * LLVMTCEBuilder::createTerminal ( const MachineOperand &  mo,
int  bitLimit = 0 
)
protected

Creates a POM source terminal from an LLVM machine operand.

Parameters
moLLVM machine operand.
Returns
POM terminal.

Definition at line 2153 of file LLVMTCEBuilder.cc.

2153 {
2154 if (bitLimit == 0) {
2155 bitLimit = mach_->is64bit() ? 64 : 32;
2156 }
2157
2158 if (mo.isReg()) {
2159 unsigned dRegNum = mo.getReg();
2160
2161 // is it the RA register?
2162 if (isTTATarget() && dRegNum == raPortDRegNum()) {
2163 return new TTAProgram::TerminalFUPort(
2164 *UniversalMachine::instance().controlUnit()->
2165 returnAddressPort());
2166 }
2167
2168 // an FU port register?
2170 if (term != NULL)
2171 return term;
2172
2173 // a general purpose register?
2174 std::string rfName = registerFileName(dRegNum);
2175 int idx = registerIndex(dRegNum);
2176 return createTerminalRegister(rfName, idx);
2177 } else if (mo.isFPImm()) {
2178 const APFloat& apf = mo.getFPImm()->getValueAPF();
2179 if (&apf.getSemantics() == &APFloat::IEEEhalf()) { //Half float
2180 APInt api = apf.bitcastToAPInt();
2181 uint16_t binary = (uint16_t)api.getRawData()[0];
2182 SimValue val(bitLimit);
2183 val = HalfFloatWord( binary );
2184 return new TTAProgram::TerminalImmediate(val);
2185 } else {
2186 float fval = apf.convertToFloat();
2187 SimValue val(bitLimit);
2188 val = fval;
2189 return new TTAProgram::TerminalImmediate(val);
2190 }
2191 } else if (mo.isImm()) {
2192 int width = bitLimit;
2193 SimValue val(mo.getImm(), width);
2194 return new TTAProgram::TerminalImmediate(val);
2195 } else if (mo.isMBB() || mo.isBlockAddress()) {
2196 return createMBBReference(mo);
2197 } else if (mo.isFI()) {
2198 std::cerr << " Frame index source operand NOT IMPLEMENTED!"
2199 << std::endl;
2200 assert(false);
2201 } else if (mo.isCPI()) {
2202 if (!functionAtATime_) {
2203 int width = bitLimit;
2204 unsigned idx = mo.getIndex();
2205 assert(currentFnCP_.find(idx) != currentFnCP_.end() &&
2206 "CPE not found!");
2207 unsigned addr = currentFnCP_[idx];
2208 SimValue cpeAddr(addr, width);
2209 return new TTAProgram::TerminalImmediate(cpeAddr);
2210 } else {
2211 // Constant Pool Index is converted to dummy
2212 // symbol reference. Will be converted back
2213 // when doing POM->LLVM transfer.
2214 // Format of reference is ".CP_INDEX_OFFSET".
2215 TCEString ref(".CP_");
2216 ref << mo.getIndex() << "_" << mo.getOffset();
2217 return createSymbolReference(ref);
2218 }
2219 } else if (mo.isJTI()) {
2220 TCEString ref(".JTI_");
2221 ref << mo.getIndex();
2222 return createSymbolReference(ref);
2223 } else if (mo.isGlobal()) {
2224 unsigned aSpaceId =
2225 cast<PointerType>(mo.getGlobal()->getType())->getAddressSpace();
2226
2227 TTAMachine::AddressSpace& aSpace =
2228 addressSpaceById(aSpaceId);
2229
2230 SmallString<256> Buffer;
2231 mang_->getNameWithPrefix(Buffer, mo.getGlobal(), false);
2232 TCEString name(Buffer.c_str());
2233
2234 if (name == END_SYMBOL_NAME) {
2235 return createSymbolReference(name);
2236 } else if (dataLabels_.find(name) != dataLabels_.end()) {
2237 SimValue address(dataLabels_[name] + mo.getOffset(), bitLimit);
2238 return new TTAProgram::TerminalAddress(address, aSpace);
2239
2240 } else {
2241 // TODO: this lacks offset??
2242 return createSymbolReference(name);
2243 }
2244 } else if (mo.isJTI()) {
2245 std::cerr << " Jump table index operand NOT IMPLEMENTED!\n";
2246 assert(false);
2247 } else if (mo.isSymbol()) {
2248 return createSymbolReference(mo);
2249 } else if (mo.isMCSymbol()) {
2251 } else if (mo.isMetadata()) {
2252 assert("Metadata MachineOperands should not get here" && false);
2253 } else {
2254 std::cerr << "Unknown src operand type!" << std::endl;
2255 // LLVM does not include dump() when built in non-debug mode.
2256 // mo.getParent()->dump();
2257 assert(false);
2258 }
2259 abortWithError("Should not get here!");
2260 return NULL;
2261}
virtual TTAProgram::Terminal * createMBBReference(const MachineOperand &mo)
TTAProgram::TerminalRegister * createTerminalRegister(const std::string &rfName, int index)
virtual unsigned raPortDRegNum() const =0
std::map< unsigned, unsigned > currentFnCP_
Constant pool for the current machine function. Map key is constant pool index and the value is addre...
virtual TTAProgram::Terminal * createFUTerminal(const MachineOperand &) const
virtual int registerIndex(unsigned llvmRegNum) const =0
virtual TCEString registerFileName(unsigned llvmRegNum) const =0
virtual TTAProgram::Terminal * createProgramOperationReference(const MachineOperand &mo)
virtual bool isTTATarget() const

References abortWithError, addressSpaceById(), assert, createFUTerminal(), createMBBReference(), createProgramOperationReference(), createSymbolReference(), createTerminalRegister(), currentFnCP_, dataLabels_, END_SYMBOL_NAME, functionAtATime_, UniversalMachine::instance(), TTAMachine::Machine::is64bit(), isTTATarget(), mach_, mang_, raPortDRegNum(), registerFileName(), and registerIndex().

Referenced by createMove(), emitComparisonForBranch(), emitInstruction(), emitLongjmp(), emitMove(), llvm::LLVMTCEPOMBuilder::emitMove(), emitOperationMacro(), emitReadSP(), emitRemaingingBrach(), emitReturnTo(), emitSelect(), emitSetjmp(), emitWriteSP(), and handleMemoryCategoryInfo().

Here is the call graph for this function:

◆ createTerminalRegister()

TTAProgram::TerminalRegister * LLVMTCEBuilder::createTerminalRegister ( const std::string &  rfName,
int  index 
)
protected

Definition at line 2124 of file LLVMTCEBuilder.cc.

2125 {
2126
2127 const RegisterFile* rf;
2128 if (!mach_->registerFileNavigator().hasItem(rfName)) {
2130 } else {
2131 rf = mach_->registerFileNavigator().item(rfName);
2132 assert(idx >= 0 && idx < rf->size());
2133 }
2134
2135 const RFPort* port = NULL;
2136 for (int i = 0; i < rf->portCount(); i++) {
2137 if (rf->port(i)->isOutput()) {
2138 port = rf->port(i);
2139 break;
2140 }
2141 }
2142 assert(port != NULL);
2143 return new TTAProgram::TerminalRegister(*port, idx);
2144}
virtual RFPort * port(const std::string &name) const
bool hasItem(const std::string &name) const
virtual RegisterFileNavigator registerFileNavigator() const
Definition Machine.cc:450
virtual bool isOutput() const
Definition Port.cc:308
virtual int portCount() const
Definition Unit.cc:135
UnboundedRegisterFile & integerRegisterFile() const

References assert, TTAMachine::Machine::Navigator< ComponentType >::hasItem(), UniversalMachine::instance(), UniversalMachine::integerRegisterFile(), TTAMachine::Port::isOutput(), TTAMachine::Machine::Navigator< ComponentType >::item(), mach_, TTAMachine::BaseRegisterFile::port(), TTAMachine::Unit::portCount(), and TTAMachine::Machine::registerFileNavigator().

Referenced by createTerminal().

Here is the call graph for this function:

◆ dataEnd()

unsigned & LLVMTCEBuilder::dataEnd ( TTAMachine::AddressSpace aSpace)
private

Returns the position after the highest written data symbol for the given address space.

Definition at line 3793 of file LLVMTCEBuilder.cc.

3793 {
3794 if (!MapTools::containsKey(dataEnds_, &aSpace)) {
3795 unsigned end =
3796 (options_ != nullptr && options_->isDataStartAddressSet(aSpace))
3797 ? options_->dataStartAddress(aSpace)
3798 : aSpace.start();
3799 /* Avoid placing data to address 0 as it may break some null pointer
3800 tests. Waste a valuable word of memory and add a dummy word to
3801 prevent writing bytes to 1,2,3 addresses and thus then avoid reading
3802 valid data from address 0. */
3803 if (end == 0) {
3804 const TCETargetMachine* tm =
3805 dynamic_cast<const TCETargetMachine*>(tm_);
3806 assert(tm != NULL);
3808 }
3809 dataEnds_[&aSpace] = end;
3810
3811 }
3812 return dataEnds_[&aSpace];
3813}
uint64_t dataStartAddress(TTAMachine::AddressSpace &aSpace) const
bool isDataStartAddressSet(TTAMachine::AddressSpace &aSpace) const
static int maxMemoryAlignment(const TTAMachine::Machine &mach)
static bool containsKey(const MapType &aMap, const KeyType &aKey)
virtual ULongWord start() const
std::map< TTAMachine::AddressSpace *, unsigned > dataEnds_
The first position after the last data in the given address space.
LLVMTCECmdLineOptions * options_
The compiler options.

References assert, MapTools::containsKey(), dataEnds_, LLVMTCECmdLineOptions::dataStartAddress(), LLVMTCECmdLineOptions::isDataStartAddressSet(), mach_, MachineInfo::maxMemoryAlignment(), options_, TTAMachine::AddressSpace::start(), and tm_.

Referenced by doFinalization(), emitConstantPool(), and initDataSections().

Here is the call graph for this function:

◆ dataMemoryForAddressSpace()

TTAProgram::DataMemory & LLVMTCEBuilder::dataMemoryForAddressSpace ( TTAMachine::AddressSpace aSpace)
private

Returns the "layout array" for the data memory of the given address space.

Definition at line 3820 of file LLVMTCEBuilder.cc.

3820 {
3821 if (!MapTools::containsKey(dmemIndex_, &aSpace)) {
3822 dmemIndex_[&aSpace] = new TTAProgram::DataMemory(aSpace);
3823 }
3824 return *dmemIndex_[&aSpace];
3825}

References MapTools::containsKey(), and dmemIndex_.

Referenced by createDataDefinition(), createFPDataDefinition(), createGlobalValueDataDefinition(), createIntDataDefinition(), emitDataDef(), emitSPInitialization(), initDataSections(), and padToAlignment().

Here is the call graph for this function:

◆ debugDataToAnnotations()

void LLVMTCEBuilder::debugDataToAnnotations ( const llvm::MachineInstr *  mi,
TTAProgram::Move move 
)
private

Helper method that converts LLVM debug data markers to Move annotations.

Definition at line 2061 of file LLVMTCEBuilder.cc.

2062 {
2063
2064 // annotate the moves generated from known ra saves.
2065 if (mi->getFlag(MachineInstr::FrameSetup)) {
2066 TTAProgram::ProgramAnnotation progAnnotation(
2068 move.setAnnotation(progAnnotation);
2069 }
2070
2071 DebugLoc dl = mi->getDebugLoc();
2072 if (!dl)
2073 return;
2074
2075 // TODO: nobody currently generates these
2076 // spill line number kludges, this is deprecated.
2077 // annotate the moves generated from known spill instructions
2078 if (dl.getLine() == 0xFFFFFFF0) {
2079 TTAProgram::ProgramAnnotation progAnnotation(
2081 move.setAnnotation(progAnnotation);
2083 } else {
2084 // handle file+line number debug info
2085
2086 bool hasDebugInfo = false;
2087 hasDebugInfo = dl.getScope() != NULL;
2088 if (hasDebugInfo) {
2089
2090 int sourceLineNumber = -1;
2091 TCEString sourceFileName = "";
2092
2093 // inspired from lib/codegen/MachineInstr.cpp
2094 sourceLineNumber = dl.getLine();
2095 sourceFileName =
2096 static_cast<TCEString>(
2097 cast<DIScope>(dl.getScope())->getFilename().str());
2098
2099 if (sourceFileName.size() >
2101 sourceFileName =
2102 sourceFileName.substr(
2103 sourceFileName.size() -
2106 }
2107 TTAProgram::ProgramAnnotation progAnnotation(
2109 sourceLineNumber);
2110 move.addAnnotation(progAnnotation);
2111
2112 if (sourceFileName != "") {
2113 TTAProgram::ProgramAnnotation progAnnotation(
2115 ANN_DEBUG_SOURCE_CODE_PATH,
2116 sourceFileName);
2117 move.addAnnotation(progAnnotation);
2118 }
2119 }
2120 }
2121}
static const size_t MAX_ANNOTATION_BYTES
Maximum number of bytes that annotation may contain.
void setAnnotation(const ProgramAnnotation &annotation)
@ ANN_DEBUG_SOURCE_CODE_LINE
The line number in the source code file the annotated move originates from.

References TTAProgram::AnnotatedInstructionElement::addAnnotation(), TTAProgram::ProgramAnnotation::ANN_DEBUG_SOURCE_CODE_LINE, TTAProgram::ProgramAnnotation::ANN_STACKUSE_RA_SAVE, TTAProgram::ProgramAnnotation::ANN_STACKUSE_SPILL, TPEF::InstructionAnnotation::MAX_ANNOTATION_BYTES, TTAProgram::AnnotatedInstructionElement::setAnnotation(), and spillMoveCount_.

Referenced by emitInstruction(), and emitOperationMacro().

Here is the call graph for this function:

◆ deleteDeadProcedures()

void LLVMTCEBuilder::deleteDeadProcedures ( )

Definition at line 1201 of file LLVMTCEBuilder.cc.

1201 {
1202 // get machine dce analysis
1203 MachineDCE& MDCE = getAnalysis<MachineDCE>();
1204
1205 for (MachineDCE::UnusedFunctionsList::iterator i =
1206 MDCE.removeableFunctions.begin();
1207 i != MDCE.removeableFunctions.end(); i++) {
1208 std::string name = *i;
1209 if (Application::verboseLevel() > 0) {
1211 << "Deleting unused function: " << name << std::endl;
1212 }
1213 TTAProgram::Procedure& notUsedProc = prog_->procedure(name);
1214 // Delete data definitions poining to the deleted procedure.
1215 for (int dmemIdx = 0; dmemIdx < prog_->dataMemoryCount(); dmemIdx++) {
1216 auto& dmem = prog_->dataMemory(dmemIdx);
1217 for (int dataDefIdx = 0; dataDefIdx < dmem.dataDefinitionCount();
1218 dataDefIdx++) {
1219 auto& dataDef = dmem.dataDefinition(dataDefIdx);
1220 if (dataDef.isInstructionAddress()) {
1221 auto instrAddr = dataDef.destinationAddress();
1222 if (instrAddr != notUsedProc.startAddress()) {
1223 continue;
1224 }
1225 if (Application::verboseLevel() > 0) {
1227 << "Deleting data definition pointing to "
1228 << "dead function: " << name << std::endl;
1229 }
1230 dmem.deleteDataDefinition(dataDefIdx);
1231 }
1232 }
1233 }
1234 prog_->removeProcedure(notUsedProc);
1235
1236 delete &notUsedProc;
1237 }
1238}
virtual Address startAddress() const
virtual Address destinationAddress() const
DataDefinition & dataDefinition(Address address) const
Definition DataMemory.cc:79
Procedure & procedure(int index) const
Definition Program.cc:622
DataMemory & dataMemory(int index) const
Definition Program.cc:967
void removeProcedure(Procedure &proc)
Definition Program.cc:901
int dataMemoryCount() const
Definition Program.cc:942
UnusedFunctionsList removeableFunctions
Definition MachineDCE.hh:97

References TTAProgram::DataMemory::dataDefinition(), TTAProgram::Program::dataMemory(), TTAProgram::Program::dataMemoryCount(), TTAProgram::DataDefinition::destinationAddress(), Application::logStream(), TTAProgram::Program::procedure(), prog_, llvm::MachineDCE::removeableFunctions, TTAProgram::Program::removeProcedure(), TTAProgram::CodeSnippet::startAddress(), and Application::verboseLevel().

Referenced by LLVMBackend::compile().

Here is the call graph for this function:

◆ doFinalization()

bool LLVMTCEBuilder::doFinalization ( Module &  M)
protected

Finalizes the POM building.

Creates data initializers. Fixes dummy code references to point the actual instructions.

Definition at line 1094 of file LLVMTCEBuilder.cc.

1094 {
1095
1096 // errs() << "Finalize LLVMPOM builder\n";
1097
1099 unsigned& dataEndPos = dataEnd(aSpace);
1100
1101 // Create new _end symbol at the end of the data memory definitions of
1102 // the default address space. This is used by malloc() to determine the
1103 // beginning of the heap.
1104 DataDef def;
1105 def.name = END_SYMBOL_NAME;
1106 def.address = dataEndPos;
1107 def.addressSpaceId = 0;
1108 def.alignment = 1;
1109 def.size = 1;
1110 def.initialize = false;
1111 emitDataDef(def);
1112 dataLabels_[def.name] = def.address;
1113
1114 // Create data initializers.
1115 for (unsigned i = 0; i < data_.size(); i++) {
1116 emitDataDef(data_[i]);
1117 }
1118 for (unsigned i = 0; i < udata_.size(); i++) {
1119 emitDataDef(udata_[i]);
1120 }
1121 for (auto cpDataDef : cpData_) {
1122 emitDataDef(cpDataDef);
1123 }
1124
1125
1126 TTAProgram::Address endAddr(dataEndPos, aSpace);
1128 END_SYMBOL_NAME, endAddr, prog_->globalScope());
1129
1130 prog_->globalScope().addDataLabel(label);
1131
1132 // Fix references to _end symbol.
1133 unsigned i = 0;
1134 for (; i < endReferences_.size(); i++) {
1135 SimValue endLoc(mach_->is64bit() ? 64 : 32);
1136 endLoc = dataEndPos;
1138 new TTAProgram::TerminalAddress(endLoc, aSpace);
1139
1140 endReferences_[i]->setSource(ea);
1141 }
1142
1143 for (DataMemIndex::const_iterator i = dmemIndex_.begin();
1144 i != dmemIndex_.end(); ++i) {
1145 prog_->addDataMemory((*i).second);
1146 }
1147
1148 // Fix references to basic blocks.
1150 std::string>::iterator mbbRefIter =
1151 mbbReferences_.begin();
1152
1153 for (; mbbRefIter != mbbReferences_.end(); mbbRefIter++) {
1154 TTAProgram::TerminalInstructionAddress* term = mbbRefIter->first;
1155
1156 std::string mbb = mbbRefIter->second;
1157 if (mbbs_.find(mbb) == mbbs_.end()) {
1158 assert(false && "MBB not found from book keeping.");
1159 }
1160 TTAProgram::Instruction& instr = *mbbs_[mbb];
1163 term->setInstructionReference(newRef);
1164 }
1165
1166 // Fix references to code labels.
1168 std::string>::iterator codeRefIter =
1169 codeLabelReferences_.begin();
1170
1171 for (; codeRefIter != codeLabelReferences_.end(); codeRefIter++) {
1172 TTAProgram::TerminalInstructionAddress* term = codeRefIter->first;
1173 std::string label = codeRefIter->second;
1174 if (codeLabels_.find(label) == codeLabels_.end()) {
1175 std::cerr << (boost::format(
1176 "Function '%s' not defined.\n") %
1177 label).str();
1178 exit(EXIT_FAILURE);
1179 }
1180
1181 TTAProgram::Instruction& instr = *codeLabels_[label];
1184
1185 term->setInstructionReference(newRef);
1186 }
1187
1188 // Add stackpointer initialization.
1190
1191#ifdef DISASSEMBLE_LLVM_OUTPUT
1192 std::ofstream outfile("llvm_output.S");
1193 outfile << POMDisassembler::disassemble(*prog_, true);
1194 outfile.close();
1195#endif
1196
1197 return false;
1198}
static std::string disassemble(const TTAProgram::Move &move)
GlobalScope & globalScope()
Definition Program.cc:180
void addDataMemory(DataMemory *dataMem)
Definition Program.cc:954
virtual void addDataLabel(const DataLabel *dataLabel)
Definition Scope.cc:415
virtual void setInstructionReference(InstructionReference ref)
Definition Terminal.cc:404
std::vector< DataDef > data_
Data definitions.
std::vector< DataDef > udata_
unsigned & dataEnd(TTAMachine::AddressSpace &aSpace)
std::map< std::string, TTAProgram::Instruction * > mbbs_
Machine basic block -> first instruction in the BB map.
virtual void emitSPInitialization()
void emitDataDef(const DataDef &def)
std::vector< ConstantDataDef > cpData_

References TTAProgram::Scope::addDataLabel(), TTAProgram::Program::addDataMemory(), llvm::LLVMTCEBuilder::DataDef::address, addressSpaceById(), llvm::LLVMTCEBuilder::DataDef::addressSpaceId, llvm::LLVMTCEBuilder::DataDef::alignment, assert, codeLabelReferences_, codeLabels_, cpData_, TTAProgram::InstructionReferenceManager::createReference(), data_, dataEnd(), dataLabels_, POMDisassembler::disassemble(), dmemIndex_, emitDataDef(), emitSPInitialization(), END_SYMBOL_NAME, endReferences_, TTAProgram::Program::globalScope(), llvm::LLVMTCEBuilder::DataDef::initialize, TTAProgram::Program::instructionReferenceManager(), TTAMachine::Machine::is64bit(), mach_, mbbReferences_, mbbs_, llvm::LLVMTCEBuilder::DataDef::name, prog_, TTAProgram::Terminal::setInstructionReference(), llvm::LLVMTCEBuilder::DataDef::size, and udata_.

Referenced by llvm::LLVMPOMBuilder::doFinalization(), llvm::LLVMTCEIRBuilder::doFinalization(), and llvm::LLVMTCEPOMBuilder::doFinalization().

Here is the call graph for this function:

◆ doInitialization()

bool LLVMTCEBuilder::doInitialization ( Module &  m)
protected

Initializer creates a new POM and adds all global data initializations.

Parameters
mModule to initialize the writer for.

Definition at line 433 of file LLVMTCEBuilder.cc.

433 {
434 mod_ = &m;
435 dataInitialized_ = false;
436 return false;
437}

References dataInitialized_, and mod_.

Referenced by llvm::LLVMTCEIRBuilder::doInitialization(), and llvm::LLVMTCEPOMBuilder::doInitialization().

◆ emitComparisonForBranch()

TTAProgram::Instruction * LLVMTCEBuilder::emitComparisonForBranch ( TCEString  firstOp,
const MachineInstr *  mi,
TTAProgram::CodeSnippet proc 
)
private

Definition at line 1731 of file LLVMTCEBuilder.cc.

1732 {
1733
1734 const HWOperation& op = getHWOperation(opName);
1735
1737 const Operation& operation = pool.operation(opName.c_str());
1739
1740 ProgramOperationPtr po(new ProgramOperation(operation, mi));
1741
1742 TTAProgram::Instruction* first = nullptr;
1743 for (int i = 0; i < 2; i++) {
1744 const MachineOperand& mo = mi->getOperand(i);
1747 auto move = createMove(src, dst, bus);
1749 if (i == 0) {
1750 first = instr;
1751 }
1752 instr->addMove(move);
1753 proc->add(instr);
1754 createMoveNode(po, move, true);
1755 }
1756
1757 // dummy result value, to universal machine register
1760 *UniversalMachine::instance().booleanRegisterFile().port(0), 0);
1761 auto move = createMove(src, dst, bus);
1763 instr->addMove(move);
1764 proc->add(instr);
1765 createMoveNode(po, move, false);
1766 return first;
1767}
std::shared_ptr< ProgramOperation > ProgramOperationPtr
Definition MoveNode.hh:53
virtual void add(Instruction *ins)
void addMove(std::shared_ptr< Move > move)
const TTAMachine::HWOperation & getHWOperation(std::string opName)
virtual void createMoveNode(ProgramOperationPtr &, std::shared_ptr< TTAProgram::Move > m, bool)
std::unique_ptr< OperationPool > pool

References TTAProgram::CodeSnippet::add(), TTAProgram::Instruction::addMove(), createMove(), createMoveNode(), createTerminal(), getHWOperation(), UniversalMachine::instance(), and UniversalMachine::universalBus().

Referenced by emitInstruction().

Here is the call graph for this function:

◆ emitConstantPool()

void LLVMTCEBuilder::emitConstantPool ( const llvm::MachineConstantPool &  cp)
protected

Reserves space and addresses for constant pool entries.

Data defitions are not emitted until in doFinalization() because CP values may refer to symbols not yet encountered such as functions and _end symbol.

The constant pool is appended to the end of the default data memory. FIXME: should be emitted before global data.

Parameters
mcpConstant pool to emit.

Definition at line 2350 of file LLVMTCEBuilder.cc.

2350 {
2351
2352 currentFnCP_.clear();
2353
2354 const std::vector<MachineConstantPoolEntry>& cp = mcp.getConstants();
2355
2356 const unsigned cpAddrSpaceId = 0;
2357 unsigned& dataEndPos = dataEnd(addressSpaceById(cpAddrSpaceId));
2358
2359 for (unsigned i = 0, e = cp.size(); i != e; ++i) {
2360 auto& cpe = cp[i];
2361 assert(!(cpe.isMachineConstantPoolEntry()) && "NOT SUPPORTED");
2362 if (!globalCP_.count(cpe.Val.ConstVal)) {
2363 // New unique constant.
2364 assert(cpe.getAlign().value() > 0);
2365 unsigned alignment = cpe.getAlign().value();
2366 padToAlignment(cpAddrSpaceId, dataEndPos, alignment);
2367 unsigned address = dataEndPos;
2368
2369 unsigned size = cpe.getSizeInBytes(*dl_);
2370 cpData_.emplace_back(ConstantDataDef(
2371 address, alignment, size, cpe.Val.ConstVal));
2372 globalCP_.insert(std::make_pair(cpe.Val.ConstVal, address));
2373 dataEndPos += size;
2374 // std::cerr << "Constant* = " << cpe.Val.ConstVal << ", "
2375 // << "value = ";
2376 // cpe.Val.ConstVal->dump();
2377 }
2378 // Map current machine function constant pool indexes to the
2379 // addresses of the global CP constants.
2380 currentFnCP_[i] = globalCP_.at(cpe.Val.ConstVal);
2381 }
2382}
std::map< const llvm::Constant *, unsigned > globalCP_
Global constant pool for all constants gathered from machine functions. Map key is unique constant an...

References addressSpaceById(), assert, cpData_, currentFnCP_, dataEnd(), dl_, globalCP_, and padToAlignment().

Referenced by writeMachineFunction(), and llvm::LLVMTCEIRBuilder::writeMachineFunction().

Here is the call graph for this function:

◆ emitDataDef() [1/2]

void LLVMTCEBuilder::emitDataDef ( const ConstantDataDef def)
private

Creates data definition from a Constant pool entry definition.

Parameters
addrAddress where the data is to be defined in the data memory.
cvConstant initializer for the data.

Definition at line 502 of file LLVMTCEBuilder.cc.

502 {
503
504#ifndef NDEBUG
505 unsigned address = def.address;
506#endif
507 createDataDefinition(0, address, def.value);
508 assert(address == def.address + def.size);
509}

References llvm::LLVMTCEBuilder::ConstantDataDef::address, assert, createDataDefinition(), llvm::LLVMTCEBuilder::ConstantDataDef::size, and llvm::LLVMTCEBuilder::ConstantDataDef::value.

Here is the call graph for this function:

◆ emitDataDef() [2/2]

void LLVMTCEBuilder::emitDataDef ( const DataDef def)
private

Creates data definition from a Constant initializer and adds it to the machine data memory.

Parameters
addrAddress where the data is to be defined in the data memory.
cvConstant initializer for the data.

Definition at line 447 of file LLVMTCEBuilder.cc.

447 {
448
449 TTAMachine::AddressSpace& aSpace =
450 addressSpaceById(def.addressSpaceId);
452
453 if (!def.initialize) {
454
455 if (def.address % def.alignment != 0) {
456 std::cerr << def.name << " misaligned!" << std::endl;
457 std::cerr << " address: " << def.address
458 << " alignment: " << def.alignment << std::endl;
459
460 assert(false);
461 }
462
463 TTAProgram::Address addr(def.address, aSpace);
466 addr, def.size, mach_->isLittleEndian()));
467
468 return;
469 } else {
470
471 const GlobalVariable* var = NULL;
472 for (Module::const_global_iterator i = mod_->global_begin();
473 i != mod_->global_end(); i++) {
474
475 SmallString<256> Buffer;
476 mang_->getNameWithPrefix(Buffer, &(*i), false);
477 if (def.name == Buffer.c_str()) {
478 var = &(*i);
479 break;
480 }
481 }
482
483 unsigned addr = def.address;
484
485 assert(var != NULL && "Variable not found!");
486
487#ifndef NDEBUG
488 unsigned paddedAddr =
489#endif
490 createDataDefinition(def.addressSpaceId, addr, var->getInitializer());
491 assert(paddedAddr == def.address);
492 }
493}

References TTAProgram::DataMemory::addDataDefinition(), llvm::LLVMTCEBuilder::DataDef::address, addressSpaceById(), llvm::LLVMTCEBuilder::DataDef::addressSpaceId, llvm::LLVMTCEBuilder::DataDef::alignment, assert, createDataDefinition(), dataMemoryForAddressSpace(), llvm::LLVMTCEBuilder::DataDef::initialize, TTAMachine::Machine::isLittleEndian(), mach_, mang_, mod_, llvm::LLVMTCEBuilder::DataDef::name, and llvm::LLVMTCEBuilder::DataDef::size.

Referenced by doFinalization().

Here is the call graph for this function:

◆ emitGlobalXXtructorCalls()

TTAProgram::Instruction * LLVMTCEBuilder::emitGlobalXXtructorCalls ( const MachineInstr *  mi,
TTAProgram::CodeSnippet proc,
bool  constructors 
)
private

Constructs moves for calling all global constructors or destructors, if any.

Parameters
miMachine instruction including the inline asm.
procTTA procedure to append moves into.
constructorsTrue, if emitting constructors, otherwise destructors.

Definition at line 3490 of file LLVMTCEBuilder.cc.

3492 {
3493
3494 std::string globalName =
3495 constructors ?
3496 ("llvm.global_ctors") : ("llvm.global_dtors");
3497
3498 TTAProgram::Instruction* firstInstruction = NULL;
3499
3500 // find the _llvm.global_Xtors global with the
3501 // function pointers and priorities
3502 for (Module::const_global_iterator i = mod_->global_begin();
3503 i != mod_->global_end(); i++) {
3504
3505 const GlobalVariable* gv = &(*i);
3506 if (gv->getName() == globalName && gv->use_empty()) {
3507 // The initializer should be an array of '{ int, void ()* }'
3508 // structs for LLVM 3.4 and lower, and an array of
3509 // '{ int, void ()*, i8* }' structs for LLVM 3.5.
3510 // The first value is the init priority, which we ignore.
3511 auto init = gv->getInitializer();
3512 if (!isa<ConstantArray>(init)) {
3513 abortWithError("Global array initializer not ConstantArray.");
3514 }
3515 const ConstantArray* initList = cast<const ConstantArray>(init);
3516 for (unsigned i = 0, e = initList->getNumOperands(); i != e; ++i) {
3517 if (ConstantStruct* cs =
3518 dyn_cast<ConstantStruct>(initList->getOperand(i))) {
3519
3520 // LLVM 3.5 introduced an additional field, so test for
3521 // an array of 3-element structs.
3522 if (cs->getNumOperands() != 3) {
3523 return firstInstruction;
3524 }
3525
3526 // Found a null terminator, exit printing.
3527 if (cs->getOperand(1)->isNullValue()) {
3528 return firstInstruction;
3529 }
3530
3531 // Emit the call.
3532 GlobalValue* gv = dyn_cast<GlobalValue>(
3533 cs->getOperand(1));
3534 assert(gv != NULL&&"global constructor name not constv");
3535
3536 SmallString<256> Buffer;
3537 mang_->getNameWithPrefix(Buffer, gv, false);
3538 TCEString name(Buffer.c_str());
3539
3540 TTAProgram::Terminal* xtorRef = NULL;
3541
3542 // cannot use instr. refs in the new builder as the
3543 // instructions won't belong in a procedure before
3544 // they have been fully scheduled.
3545 xtorRef = new TTAProgram::TerminalSymbolReference(name);
3546
3547 CodeGenerator codeGenerator(*mach_);
3548
3549 auto ctrCall =
3550 std::make_shared<TTAProgram::Move>(
3551 xtorRef, codeGenerator.createTerminalFUPort("call", 1),
3553
3554 OperationPool opPool;
3555
3556 // Create ProgramOperation also for return so DDGBuilder does not have
3557 // to do that.
3559 new ProgramOperation(opPool.operation("call")));
3560 createMoveNode(po, ctrCall, true);
3561
3562 TTAProgram::Instruction* newInstr =
3565
3566 newInstr->addMove(ctrCall);
3567 proc->add(newInstr);
3568
3569 if (firstInstruction == NULL)
3570 firstInstruction = &proc->lastInstruction();
3571 }
3572 }
3573 return firstInstruction;
3574 }
3575 }
3576 return NULL;
3577}
Operation & operation(const char *name)
static NullInstructionTemplate & instance()
virtual Instruction & lastInstruction() const

References abortWithError, TTAProgram::CodeSnippet::add(), TTAProgram::Instruction::addMove(), assert, createMoveNode(), TTAProgram::CodeGenerator::createTerminalFUPort(), TTAMachine::NullInstructionTemplate::instance(), UniversalMachine::instance(), TTAProgram::CodeSnippet::lastInstruction(), mach_, mang_, mod_, OperationPool::operation(), and UniversalMachine::universalBus().

Referenced by emitSpecialInlineAsm().

Here is the call graph for this function:

◆ emitInlineAsm()

TTAProgram::Instruction * LLVMTCEBuilder::emitInlineAsm ( const MachineFunction &  mf,
const MachineInstr *  mi,
TTAProgram::BasicBlock bb,
TTAProgram::InstructionReferenceManager irm 
)
protected

Handles INLINEASM nodes that hold real inline assembly code.

This method should not be called for pseudo inline assembly - like TCE operation macros (see emitOperationMacro()).

Definition at line 2790 of file LLVMTCEBuilder.cc.

2794 {
2795
2796 assert(isInlineAsm(*mi));
2797 assert(bb->instructionCount() == 0 && "Expected empty BB.");
2798
2799 const TCETargetMachine* tm = dynamic_cast<const TCETargetMachine*>(tm_);
2800 assert(tm && "Inline asm parser requires TCETargetMachine.");
2801
2802 // Avoid unintended overwrite of reserved registers.
2803 auto asmOpds = getInlineAsmOperands(*mi);
2804 for (auto& opds : asmOpds) {
2805 auto& asmOpdNodes = std::get<1>(opds.second);
2806 for (auto mo : asmOpdNodes) {
2807 if (!mo->isReg() ||
2808 !mf.getRegInfo().isReserved(mo->getReg())) {
2809 continue;
2810 }
2811 auto srcLoc = getSourceLocationString(*mi);
2812 std::cerr << srcLoc
2813 << "Error: An use of reserved register '"
2814 << tm->registerName(mo->getReg())
2815 << "' in inline assembly." << std::endl;
2818 "Encountered errors in inline assembly.");
2819 }
2820 }
2821
2822 // Static since the parser has state for "%=" template strings.
2823 static InlineAsmParser inlineAsmParser(*tm, *mang_);
2824
2825 if (!inlineAsmParser.parse(*mi, dataLabels_, *bb, irm)) {
2826 auto& diag = inlineAsmParser.diagnostics();
2827 auto srcLoc = getSourceLocationInfo(*mi);
2828 if (!std::get<0>(srcLoc).empty()) {
2829 std::cerr << std::get<0>(srcLoc) << ":" << std::get<1>(srcLoc)
2830 << ":" << std::endl;
2831 }
2832 for (auto syntaxError : diag.errors()) {
2833 std::cerr << "Error in line " << syntaxError.lineNumber << ": "
2834 << syntaxError.message << std::endl;
2835 }
2836 for (auto internalError : diag.otherErrors()) {
2837 std::cerr << "Error: " << internalError.message << std::endl;
2838 }
2840 CompileError, "Encountered errors in inline assembly parsing.");
2841 }
2842
2844 for (auto warning : inlineAsmParser.diagnostics().warnings()) {
2845 // TODO point to line in C code.
2846 std::cerr << warning.toString() << std::endl;
2847 }
2848 }
2849
2850 return bb->instructionCount() ? &bb->instructionAtIndex(0)
2851 : nullptr;
2852}
#define THROW_EXCEPTION(exceptionType, message)
Exception wrapper macro that automatically includes file name, line number and function name where th...
Definition Exception.hh:39
std::string getSourceLocationString(const llvm::MachineInstr &mi)
AsmOperandMap getInlineAsmOperands(const llvm::MachineInstr &mi)
POP_COMPILER_DIAGS std::tuple< std::string, size_t > getSourceLocationInfo(const llvm::MachineInstr &mi)
virtual int instructionCount() const
virtual Instruction & instructionAtIndex(int index) const
static bool isInlineAsm(const MachineInstr &instr)
std::string registerName(unsigned dwarfRegNum) const

References assert, dataLabels_, InlineAsmParser::diagnostics(), getInlineAsmOperands(), getSourceLocationInfo(), getSourceLocationString(), TTAProgram::CodeSnippet::instructionAtIndex(), TTAProgram::CodeSnippet::instructionCount(), isInlineAsm(), mang_, options_, InlineAsmParser::parse(), LLVMTCECmdLineOptions::printInlineAsmWarnings(), llvm::TCETargetMachine::registerName(), THROW_EXCEPTION, tm_, and AssemblyParserDiagnostic::warnings().

Referenced by llvm::LLVMTCEIRBuilder::buildTCECFG().

Here is the call graph for this function:

◆ emitInstruction()

TTAProgram::Instruction * LLVMTCEBuilder::emitInstruction ( const MachineInstr *  mi,
TTAProgram::CodeSnippet proc 
)
protected

Creates POM instructions from a LLVM MachineInstruction.

One POM instruction per Move are created.

Parameters
miMachine instruction to emit to the POM.
procPOM procedure to append the instruction to.
Returns
First of the POM instructions emitted.

Definition at line 1326 of file LLVMTCEBuilder.cc.

1327 {
1328
1329 bool isSpill = false;
1330 bool isRaSlot = false;
1331 bool isFpSlot = false;
1332 const llvm::MCInstrDesc* opDesc = &mi->getDesc();
1333 unsigned opc = mi->getDesc().getOpcode();
1334
1335 // when the -g option turn on, this will come up opc with this, therefore
1336 // add this to ignore however, it is uncertain whether the debug "-g" will
1337 // generate more opc, need to verify
1338 // NOTE there is similar code in ConstantTransformer::runOnMachineFunction
1339 if (opc == TargetOpcode::DBG_VALUE
1340 || opc == TargetOpcode::DBG_LABEL
1341 || opc == TargetOpcode::DBG_INSTR_REF
1342 || opc == TargetOpcode::DBG_VALUE_LIST
1343 || opc == TargetOpcode::DBG_PHI
1344 || opc == TargetOpcode::KILL) {
1345 return NULL;
1346 }
1347
1348 std::string opName = "";
1349
1350 bool hasGuard = false;
1351 bool trueGuard = true;
1352 if (dynamic_cast<const TCETargetMachine*>(&targetMachine()) != NULL) {
1353
1354 if (opDesc->isReturn()) {
1355 // in case of TTA targets, the return node needs to be
1356 // converted to ra -> jump here as it does not map 1:1
1357 // with the DAG names and we map LLVM DAG names to OSAL
1358 // operations
1359 // FIXME: this is the wrong way to do this:
1360 // should LowerReturn to RA -> JUMP.1 instead and process just
1361 // like any other operation here.
1362 return emitReturn(mi, proc);
1363 }
1364 opName = operationName(*mi);
1365
1366 // Pseudo instructions don't require any actual instructions.
1367 if (opName == "PSEUDO" || opName == "DEBUG_LABEL") {
1368 return NULL;
1369 }
1370
1371 // Debug labels don't require any actual instructions.
1372 // TODO: should store the data and apply to next? (or prev?) instr,
1373 // but just ignore it to not cause a crash.
1374 if (opName =="DEBUG_LABEL") {
1375 return nullptr;
1376 }
1377
1378 if (opName[0] == '?') {
1379 hasGuard = true;
1380 opName = opName.substr(1);
1381 }
1382
1383 if (opName[0] == '!') {
1384 hasGuard = true;
1385 trueGuard = false;
1386 opName = opName.substr(1);
1387 }
1388
1389 if (opName == "MOVE") {
1390 return emitMove(mi, proc, hasGuard, trueGuard);
1391 }
1392
1393 // TODO: guarded also for these
1394 if (opName == "INLINEASM") {
1395 return emitOperationMacro(mi, proc);
1396 }
1397
1398 if (opName == "CMOV_SELECT") {
1399 return emitSelect(mi, proc);
1400 }
1401 } else {
1402 opName = operationName(*mi);
1403 }
1404
1405 // split compare + jump combo op.
1406 size_t split = opName.find("+");
1407 if (split != std::string::npos) {
1408 TCEString firstOp = opName.substr(0, split);
1409 TCEString remainingName = opName.substr(split+1);
1410 TTAProgram::Instruction* ins = emitComparisonForBranch(firstOp, mi, proc);
1411 emitRemaingingBrach(remainingName, mi, proc);
1412 return ins;
1413 }
1414
1415 const HWOperation& op = getHWOperation(opName);
1416
1418
1420 const Operation& operation = pool.operation(opName.c_str());
1421
1422 std::vector<TTAProgram::Instruction*> operandMoves;
1423 std::vector<TTAProgram::Instruction*> resultMoves;
1424
1425 int inputOperand = 0;
1426 int outputOperand = operation.numberOfInputs();
1427#ifdef DEBUG_LLVMTCEBUILDER
1428 PRINT_VAR(operation.numberOfInputs());
1429 PRINT_VAR(operation.numberOfOutputs());
1430 Application::logStream() << " mi->getNumOperands() = "
1431 << mi->getNumOperands() << std::endl;
1432#endif
1433 TTAProgram::MoveGuard* guard = NULL;
1434 int guardOperandIndex = -1;
1435
1436 if (hasGuard) {
1437 for (unsigned o = 0; o < mi->getNumOperands(); o++) {
1438 const MachineOperand& mo = mi->getOperand(o);
1439
1440 // Guarded operations have the guarded element as the first
1441 // operand.
1442
1443 if (mo.isReg() && mo.isUse()) {
1444 guardOperandIndex = o;
1445 // Create move from the condition operand register to bool
1446 // register which is used by the guard.
1448 // inv guards not yet supported
1449 guard = createGuard(t, trueGuard);
1450 delete t;
1451 assert(guard != NULL);
1452 break;
1453 }
1454 }
1455 }
1456
1457
1458 for (unsigned o = 0; o < mi->getNumOperands(); o++) {
1459 if ((int)o == guardOperandIndex) {
1460 continue;
1461 }
1462
1463 const MachineOperand& mo = mi->getOperand(o);
1464 TTAProgram::Terminal* src = NULL;
1465 TTAProgram::Terminal* dst = NULL;
1466
1467 if (!mo.isReg() || mo.isUse() || operation.numberOfOutputs() == 0) {
1468 ++inputOperand;
1469 if (inputOperand > operation.numberOfInputs()) {
1470
1471 if (mo.isMetadata()) {
1472 const MDNode* mdNode = mo.getMetadata();
1473 for (unsigned int i = 0; i < mdNode->getNumOperands(); i++) {
1474 const MDOperand & oper = mdNode->getOperand(i);
1475 if (llvm::MDString* mds = dyn_cast<llvm::MDString>(oper)) {
1476 TCEString s = mds->getString().str();
1477 if (s == "AA_CATEGORY_STACK_SLOT") {
1478 isSpill = true;
1479 } else if (s == "AA_CATEGORY_RA_SAVE_SLOT") {
1480 isRaSlot = true;
1481 } else if (s == "AA_CATEGORY_FP_SAVE_SLOT") {
1482 isFpSlot = true;
1483 }
1484 }
1485 }
1486 }
1487 continue;
1488 }
1489
1490 assert(operation.operand(inputOperand).isInput() &&
1491 "Operand mismatch.");
1492
1493 // currently the input operand of the base+offset mem operations
1494 // are not marked as addresses as alias analysis does not work
1495 // in that case correctly, thus we have to treat those operations
1496 // as special cases for the time being
1497 if (operation.operand(inputOperand).isAddress() ||
1498 (operation.isBaseOffsetMemOperation() && inputOperand == 1)) {
1499 // MachineInstructions have two operands for each Operation
1500 // address operand: base and offset immediate, split it to
1501 // two in case of an add+ld/st.
1502 const MachineOperand& base = mo;
1503 src = createTerminal(base);
1504 dst = new TTAProgram::TerminalFUPort(op, inputOperand);
1505 TTAProgram::MoveGuard* guardCopy =
1506 guard == NULL ? NULL : guard->copy();
1507
1508 auto move = createMove(src, dst, bus, guardCopy);
1510 instr->addMove(move);
1511
1512 operandMoves.push_back(instr);
1513
1514 debugDataToAnnotations(mi, *move);
1515 addPointerAnnotations(mi, *move);
1516 o += 1;
1517 const MachineOperand& offset = mi->getOperand(o);
1518 if (operation.isBaseOffsetMemOperation()) {
1519 ++inputOperand;
1520 // the offset is always the 2nd operand for the standard
1521 // base+offset ops
1522 assert(inputOperand == 2);
1523
1524 // create the offset operand move
1525 src = createTerminal(offset);
1526 dst = new TTAProgram::TerminalFUPort(op, inputOperand);
1527 TTAProgram::MoveGuard* guardCopy =
1528 guard == NULL ? NULL : guard->copy();
1529
1530 auto move = createMove(src, dst, bus, guardCopy);
1531 instr = new TTAProgram::Instruction();
1532 instr->addMove(move);
1533 operandMoves.push_back(instr);
1534 debugDataToAnnotations(mi, *move);
1535 } else {
1536 assert(offset.getImm() == 0);
1537 }
1538 } else {
1539 src = createTerminal(mo);
1540 dst = new TTAProgram::TerminalFUPort(op, inputOperand);
1541 TTAProgram::MoveGuard* guardCopy =
1542 guard == NULL ? NULL : guard->copy();
1543
1544 auto move = createMove(src, dst, bus, guardCopy);
1546 instr->addMove(move);
1547#ifdef DEBUG_LLVMTCEBUILDER
1549 << "adding " << move->toString() << std::endl;
1550#endif
1551 operandMoves.push_back(instr);
1552 debugDataToAnnotations(mi, *move);
1553 }
1554 } else {
1555 ++outputOperand;
1556 if (operation.operand(outputOperand).isNull())
1557 continue;
1558
1559 assert(operation.operand(outputOperand).isOutput() &&
1560 !operation.operand(outputOperand).isAddress() &&
1561 "Operand mismatch.");
1562
1563 src = new TTAProgram::TerminalFUPort(op, outputOperand);
1564 dst = createTerminal(mo);
1565
1566 TTAProgram::MoveGuard* guardCopy =
1567 guard == NULL ? NULL : guard->copy();
1568
1569 auto move = createMove(src, dst, bus, guardCopy);
1571 instr->addMove(move);
1572#ifdef DEBUG_LLVMTCEBUILDER
1574 << "adding " << move->toString() << std::endl;
1575#endif
1576 resultMoves.push_back(instr);
1577 debugDataToAnnotations(mi, *move);
1578 }
1579 } // End of for each MI Operand
1580
1581 for (unsigned int i = 0; i < resultMoves.size();i++) {
1582 TTAProgram::Instruction& resultIns = *resultMoves[i];
1583 for (int j = 0; j < resultIns.moveCount(); j++) {
1584 TTAProgram::Move& resultMove = resultIns.move(j);
1585 // if some operand was mem operand, copy the addr space annotations from that operand
1586 copyFUAnnotations(operandMoves, resultMove);
1587 }
1588 }
1589 // Return the first instruction of the whole operation.
1590 TTAProgram::Instruction* first = NULL;
1591 if (!operandMoves.empty()) {
1592 first = operandMoves[0];
1593 } else if (!resultMoves.empty()) {
1594 first = resultMoves[0];
1595 } else if (opDesc->isReturn() && mi->getNumOperands() == 0) {
1596 // LLVM allows RET without any paramters and with defined return value.
1597 // RET with return value is converted above but not the other one.
1598 // To convert it to move, we just write 0 as source terminal.
1599 // LLVM already generated code to put return address on a top of the stack,
1600 // so no point explicitely writing ra -> ret.1.
1601 const TTAMachine::HWOperation* jump = &getHWOperation(opName);
1603 new TTAProgram::TerminalFUPort(*jump, 1);
1604 int width = mach_->is64bit() ? 64 : 32;
1605 SimValue val(0, width);
1606
1607 auto move = createMove(
1608 new TTAProgram::TerminalImmediate(val), dst, bus);
1610 instr->addMove(move);
1611 operandMoves.push_back(instr);
1612 first = instr;
1613 debugDataToAnnotations(mi, *move);
1614 } else {
1615 assert(false && "No moves?");
1616 }
1617 ProgramOperationPtr po(new ProgramOperation(operation, mi));
1618
1619 // Read candidate FUs from MachineInstr metadata.
1620 std::vector<std::string> candidateFUs;
1621 for (unsigned i = 0; i < mi->getNumOperands(); ++i) {
1622
1623 const MachineOperand& op = mi->getOperand(i);
1624 if (!op.isMetadata()) continue;
1625 const MDNode* mdNode = op.getMetadata();
1626 if (mdNode->getNumOperands() > 0) {
1627
1628 llvm::Metadata* op = mdNode->getOperand(0);
1629 MDString* str = dyn_cast<llvm::MDString>(op);
1630
1631 if (str->getString().str() == "fu_candidates") {
1632 for (unsigned j = 1; j < mdNode->getNumOperands(); ++j) {
1633 op = mdNode->getOperand(j);
1634 str = dyn_cast<MDString>(op);
1635 TCEString fuName = str->getString().str();
1636 /* The metadata from MachineInstr might contain "illegal"
1637 FU candidates, pointing to FUs that do not contain the
1638 operation. Filter them out. */
1639 if (mach_->functionUnitNavigator().hasItem(fuName) &&
1640 mach_->functionUnitNavigator().item(fuName)->
1641 hasOperation(operation.name())) {
1642#ifdef DEBUG_LLVMTCEBUILDER
1644 << "FU candidate " << str->getString().str() << " set for ";
1645 mi->dump();
1646#endif
1647 candidateFUs.push_back(str->getString().str());
1648 }
1649 }
1650 }
1651 }
1652 }
1653
1654 for (unsigned i = 0; i < operandMoves.size(); i++) {
1655 TTAProgram::Instruction* instr = operandMoves[i];
1656 auto m = instr->movePtr(0);
1657
1658 // Add candidate FUs as DST candidates
1659 for (unsigned j = 0; j < candidateFUs.size(); ++j) {
1660 if (m->hasAnnotations(
1662 !m->hasAnnotation(
1664 candidateFUs[j]))
1665 continue; // do not add candidates that are not allowed
1666
1667 m->addAnnotation(
1670 }
1671
1672 // create the memory category annotations
1673 if (isSpill) {
1674 m->addAnnotation(
1677 } else if (isRaSlot) {
1678 m->addAnnotation(
1681 } else if (isFpSlot) {
1682 m->addAnnotation(
1685 }
1686
1687 proc->add(instr);
1688 createMoveNode(po, m, true);
1689 }
1690 for (unsigned i = 0; i < resultMoves.size(); i++) {
1691 TTAProgram::Instruction* instr = resultMoves[i];
1692 auto m = instr->movePtr(0);
1693
1694 // Add candidate FUs as SRC candidates
1695 for (unsigned j = 0; j < candidateFUs.size(); ++j) {
1696 if (m->hasAnnotations(
1698 !m->hasAnnotation(
1700 candidateFUs[j]))
1701 continue; // do not add candidates that are not allowed
1702
1703 m->addAnnotation(TTAProgram::ProgramAnnotation(
1705 }
1706
1707 // create the memory category annotations
1708 if (isSpill) {
1709 m->addAnnotation(
1712 } else if (isRaSlot) {
1713 m->addAnnotation(
1716 } else if (isFpSlot) {
1717 m->addAnnotation(
1720 }
1721
1722 proc->add(instr);
1723 createMoveNode(po, m, false);
1724 }
1725
1726 delete guard; guard = NULL;
1727 return first;
1728}
#define PRINT_VAR(VARIABLE__)
virtual bool isAddress() const
Definition Operand.cc:328
virtual bool isInput() const
Definition Operand.cc:145
virtual bool isOutput() const
Definition Operand.cc:155
virtual bool isNull() const
Definition Operand.hh:130
virtual TCEString name() const
Definition Operation.cc:93
virtual bool isBaseOffsetMemOperation() const
Definition Operation.cc:323
virtual int numberOfInputs() const
Definition Operation.cc:192
virtual int numberOfOutputs() const
Definition Operation.cc:202
virtual Operand & operand(int id) const
Definition Operation.cc:541
std::shared_ptr< Move > movePtr(int i) const
Move & move(int i) const
MoveGuard * copy() const
Definition MoveGuard.cc:96
@ ANN_CONN_CANDIDATE_UNIT_DST
Dst. unit candidate.
@ ANN_CONN_CANDIDATE_UNIT_SRC
Src. unit candidate.
@ ANN_STACKUSE_FP_SAVE
frame ptr save/load
void copyFUAnnotations(const std::vector< TTAProgram::Instruction * > &operandMoves, TTAProgram::Move &move) const
TTAProgram::Instruction * emitSelect(const MachineInstr *mi, TTAProgram::CodeSnippet *proc)
TTAProgram::Instruction * emitComparisonForBranch(TCEString firstOp, const MachineInstr *mi, TTAProgram::CodeSnippet *proc)
TTAProgram::Instruction * emitOperationMacro(const MachineInstr *mi, TTAProgram::CodeSnippet *proc)
TTAProgram::Instruction * emitRemaingingBrach(TCEString opName, const MachineInstr *mi, TTAProgram::CodeSnippet *proc)
void debugDataToAnnotations(const llvm::MachineInstr *mi, TTAProgram::Move &move)
TTAProgram::MoveGuard * createGuard(const TTAProgram::Terminal *guardReg, bool trueOrFalse)
const TargetMachine & targetMachine() const
virtual TCEString operationName(const MachineInstr &mi) const =0
void addPointerAnnotations(const llvm::MachineInstr *mi, TTAProgram::Move &move)
virtual TTAProgram::Instruction * emitMove(const MachineInstr *mi, TTAProgram::CodeSnippet *proc, bool conditional=false, bool trueGuard=true)
TTAProgram::Instruction * emitReturn(const MachineInstr *mi, TTAProgram::CodeSnippet *proc)

References TTAProgram::CodeSnippet::add(), TTAProgram::Instruction::addMove(), addPointerAnnotations(), TTAProgram::ProgramAnnotation::ANN_ALLOWED_UNIT_DST, TTAProgram::ProgramAnnotation::ANN_ALLOWED_UNIT_SRC, TTAProgram::ProgramAnnotation::ANN_CONN_CANDIDATE_UNIT_DST, TTAProgram::ProgramAnnotation::ANN_CONN_CANDIDATE_UNIT_SRC, TTAProgram::ProgramAnnotation::ANN_STACKUSE_FP_SAVE, TTAProgram::ProgramAnnotation::ANN_STACKUSE_RA_SAVE, TTAProgram::ProgramAnnotation::ANN_STACKUSE_SPILL, assert, TTAProgram::MoveGuard::copy(), copyFUAnnotations(), createGuard(), createMove(), createMoveNode(), createTerminal(), debugDataToAnnotations(), emitComparisonForBranch(), emitMove(), emitOperationMacro(), emitRemaingingBrach(), emitReturn(), emitSelect(), TTAMachine::Machine::functionUnitNavigator(), getHWOperation(), TTAMachine::Machine::Navigator< ComponentType >::hasItem(), UniversalMachine::instance(), TTAMachine::Machine::is64bit(), Operand::isAddress(), Operation::isBaseOffsetMemOperation(), Operand::isInput(), Operand::isNull(), Operand::isOutput(), TTAMachine::Machine::Navigator< ComponentType >::item(), Application::logStream(), mach_, TTAProgram::Instruction::move(), TTAProgram::Instruction::moveCount(), TTAProgram::Instruction::movePtr(), Operation::name(), Operation::numberOfInputs(), Operation::numberOfOutputs(), Operation::operand(), operationName(), PRINT_VAR, targetMachine(), and UniversalMachine::universalBus().

Referenced by llvm::LLVMTCEIRBuilder::buildTCECFG(), and writeMachineFunction().

Here is the call graph for this function:

◆ emitLoad()

TTAProgram::Instruction * llvm::LLVMTCEBuilder::emitLoad ( const MachineInstr *  mi,
TTAProgram::CodeSnippet proc 
)
private

◆ emitLongjmp()

TTAProgram::Instruction * LLVMTCEBuilder::emitLongjmp ( const MachineInstr *  mi,
TTAProgram::CodeSnippet proc 
)
private

Constructs moves for ".longjmp"

Parameters
miMachine instruction including the inline asm.
procTTA procedure to emit moves into.
Returns
First instruction in emitted block.

Definition at line 3588 of file LLVMTCEBuilder.cc.

3589 {
3590
3591 if (mi->getNumOperands() != 7) {
3592 std::cerr << "ERROR: wrong number of operands in "".longjmp"""
3593 << std::endl;
3594 assert(false);
3595 }
3596 const MachineOperand& env = mi->getOperand(3);
3597 const MachineOperand& val = mi->getOperand(5);
3598
3599 // Get the stack pointer. It will be used as index into
3600 // the buffer.
3601 unsigned spDRN = spDRegNum();
3602 TCEString sp = (boost::format("%s.%d") %
3603 registerFileName(spDRN) %
3604 registerIndex(spDRN)).str();
3605
3606 // We need to know where current procedure ends to
3607 // be able to return first generated instruction.
3608 int oldSize = proc->instructionCount();
3609
3610 CodeGenerator codeGenerator(*mach_);
3611
3612 // First thing we need is to load buffer address in SP.
3613 TTAProgram::Terminal* buffer = createTerminal(env);
3614 TTAProgram::Terminal* spTerminal =
3615 codeGenerator.createTerminalRegister(sp, false);
3616
3617 codeGenerator.addMoveToProcedure(*proc, buffer, spTerminal);
3618
3619 // Increment index to jump over the place where SP was
3620 // stored.
3621 codeGenerator.incrementStackPointer(*proc, sp);
3622
3623 // Jump over RA (will be restored in setjmp tail).
3624 codeGenerator.incrementStackPointer(*proc, sp);
3625
3626 // Now save the desired return value.
3628 codeGenerator.pushToStack(*proc, sp, rv);
3629
3630 // Reload all registers but SP.
3633
3634 for (int i = 0; i < nav.count(); i++) {
3635 const TTAMachine::RegisterFile& rf = *nav.item(i);
3636 for (int j = 0; j < rf.numberOfRegisters(); j++) {
3637 TCEString reg =
3638 (boost::format("%s.%d") % rf.name() % j).str();
3639 if (reg != sp) {
3640 // Using fromStack as I am restoring towards
3641 // higher memory addresses.
3642 codeGenerator.popRegisterFromStack(*proc, sp, reg);
3643 }
3644 }
3645 }
3646
3647 // Done, jump to setjmp ending code.
3648 codeGenerator.loadFromRegisterAddress(*proc, sp, "RA");
3649 codeGenerator.registerJump(*proc, "RA");
3650
3651 return &(proc->instructionAtIndex(oldSize));
3652}
virtual int numberOfRegisters() const
virtual TCEString name() const
virtual unsigned spDRegNum() const =0

References TTAProgram::CodeGenerator::addMoveToProcedure(), assert, TTAMachine::Machine::Navigator< ComponentType >::count(), createTerminal(), TTAProgram::CodeGenerator::createTerminalRegister(), TTAProgram::CodeGenerator::incrementStackPointer(), TTAProgram::CodeSnippet::instructionAtIndex(), TTAProgram::CodeSnippet::instructionCount(), TTAMachine::Machine::Navigator< ComponentType >::item(), TTAProgram::CodeGenerator::loadFromRegisterAddress(), mach_, TTAMachine::Component::name(), TTAMachine::BaseRegisterFile::numberOfRegisters(), TTAProgram::CodeGenerator::popRegisterFromStack(), TTAProgram::CodeGenerator::pushToStack(), registerFileName(), TTAMachine::Machine::registerFileNavigator(), registerIndex(), TTAProgram::CodeGenerator::registerJump(), and spDRegNum().

Referenced by emitSpecialInlineAsm().

Here is the call graph for this function:

◆ emitMove()

TTAProgram::Instruction * LLVMTCEBuilder::emitMove ( const MachineInstr *  mi,
TTAProgram::CodeSnippet proc,
bool  conditional = false,
bool  trueGuard = true 
)
protectedvirtual

Creates POM instruction for a move.

Parameters
miMove machine instruction.
procPOM procedure to add the move to.
Returns
Emitted POM instruction.

Reimplemented in llvm::LLVMTCEPOMBuilder.

Definition at line 2422 of file LLVMTCEBuilder.cc.

2424 {
2425
2426 unsigned int operandCount = conditional ? 3 : 2;
2427 if (mi->getNumOperands() > operandCount) {
2428 for (unsigned int i = operandCount; i < mi->getNumOperands(); i++) {
2429#if 0
2430 if (!(mi->getOperand(i).isMetadata()) &&
2431 (!mi->getOperand(i).isImplicit())) {
2432 mi->dump();
2433 }
2434#endif
2435 assert(mi->getOperand(i).isMetadata() ||
2436 mi->getOperand(i).isImplicit());
2437 }
2438 }
2439
2440 assert(mi->getNumOperands() >= operandCount); // src, dst
2441
2442 const MachineOperand& dst = mi->getOperand(0);
2443 const MachineOperand& src = mi->getOperand(operandCount - 1);
2444 TTAProgram::MoveGuard* guard = NULL;
2445 if (conditional) {
2446 const MachineOperand& gmo = mi->getOperand(1);
2447 assert (gmo.isReg() && gmo.isUse());
2448 // Create move from the condition operand register to bool register
2449 // which is used by the guard.
2451 // inv guards not yet supported
2452 guard = createGuard(t, trueGuard);
2453 }
2454
2455 TTAProgram::Terminal* dstTerm = createTerminal(dst);
2456 TTAProgram::Terminal* srcTerm =
2457 createTerminal(src, dstTerm->port().width());
2458
2459 if (srcTerm->isGPR() && dstTerm->isGPR() &&
2460 &srcTerm->registerFile() == &dstTerm->registerFile()) {
2461
2462 // Omit no-op copies.
2463 if (srcTerm->index() == dstTerm->index())
2464 return NULL;
2465
2466 if (srcTerm->registerFile().portCount() == 1) {
2467 // Cannot perform a reg2reg move with single ported register
2468 // files, need to find another way to perform the copy.
2469 const TTAMachine::HWOperation* copyOp = NULL;
2470
2471 // Use only operations which get imm 0 as the other operand
2472 // for the lowest immediate requirements.
2473 if (mach_->hasOperation("XOR")) {
2474 copyOp = &getHWOperation("XOR");
2475 } else if (mach_->hasOperation("OR")) {
2476 copyOp = &getHWOperation("OR");
2477 } else if (mach_->hasOperation("ADD")) {
2478 copyOp = &getHWOperation("ADD");
2479 }
2480
2481 if (copyOp == NULL || guard != NULL) {
2484 TCEString("Unable to create a reg to reg copy due to "
2485 "having only one port in '") +
2486 srcTerm->registerFile().name() + "'.");
2487 }
2488
2489 SimValue val(0, mach_->is64bit() ? 64 : 32);
2490
2494 new TTAProgram::TerminalFUPort(*copyOp, 1);
2495 TTAProgram::TerminalFUPort* trigTerm =
2496 new TTAProgram::TerminalFUPort(*copyOp, 2);
2498 new TTAProgram::TerminalFUPort(*copyOp, 3);
2499
2500 Application::logStream() << "Created a reg to reg copy due to RF "
2501 << srcTerm->registerFile().name()
2502 << " having only 1 port" << std::endl;
2503 CodeGenerator codeGenerator(*mach_);
2504 // 0 -> OP.1
2505 codeGenerator.addMoveToProcedure(*proc, immTerm, oprTerm);
2506 // RF.X -> OP.2
2507 codeGenerator.addMoveToProcedure(*proc, srcTerm, trigTerm);
2508 // OP.3 -> RF.Y
2509 return codeGenerator.addMoveToProcedure(*proc, resTerm, dstTerm);
2510 }
2511 }
2513 auto move = createMove(srcTerm, dstTerm, bus, guard);
2514
2515 if (move == NULL) {
2516 return NULL;
2517 }
2519
2520 instr->addMove(move);
2521 proc->add(instr);
2522 return instr;
2523}
bool hasOperation(const TCEString &opName) const
Definition Machine.cc:1042
virtual int index() const
Definition Terminal.cc:274
virtual bool isGPR() const
Definition Terminal.cc:107
virtual const TTAMachine::RegisterFile & registerFile() const
Definition Terminal.cc:225

References TTAProgram::CodeSnippet::add(), TTAProgram::Instruction::addMove(), TTAProgram::CodeGenerator::addMoveToProcedure(), assert, createGuard(), createMove(), createTerminal(), getHWOperation(), TTAMachine::Machine::hasOperation(), TTAProgram::Terminal::index(), UniversalMachine::instance(), TTAMachine::Machine::is64bit(), TTAProgram::Terminal::isGPR(), Application::logStream(), mach_, TTAMachine::Component::name(), TTAProgram::Terminal::port(), TTAMachine::Unit::portCount(), TTAProgram::Terminal::registerFile(), THROW_EXCEPTION, UniversalMachine::universalBus(), and TTAMachine::Port::width().

Referenced by emitInstruction(), and llvm::LLVMTCEPOMBuilder::emitMove().

Here is the call graph for this function:

◆ emitOperationMacro()

TTAProgram::Instruction * LLVMTCEBuilder::emitOperationMacro ( const MachineInstr *  mi,
TTAProgram::CodeSnippet proc 
)
private

Handles operation macros which too uses INLINEASM nodes.

Here the inline assembly string is expected to be just a name of a (custom) operation. Operation operands are expected to be listed as the inline assembly use and def registers. Architecture specific pseudo assembly constructs are also supported (they start with dot) and are delegated to emitSpecialInlineAsm().

Definition at line 2864 of file LLVMTCEBuilder.cc.

2865 {
2866
2867// mi->print(llvm::dbgs()); //DEBUG
2868
2869#ifndef NDEBUG
2870 unsigned numOperands =
2871#endif
2872 mi->getNumOperands();
2873 // Count the number of register definitions.
2874 unsigned numDefs = 0;
2875 for (; mi->getOperand(numDefs).isReg() &&
2876 mi->getOperand(numDefs).isDef();
2877 ++numDefs) {
2878
2879 }
2880 std::string opName = mi->getOperand(numDefs).getSymbolName();
2881
2882 // ignore the dummy placeholder asm string
2883 if (opName == "") {
2884 return NULL;
2885 }
2886
2887 if (opName[0] == '.') {
2888 // Special handling for dotted architecture-dependent asm contructs,
2889 // a.k.a. "pseudo assembly strings"
2890 return emitSpecialInlineAsm(opName, mi, proc);
2891 }
2892
2893 std::vector<std::string> addressedFUs;
2894 // test this is an addressable instruction
2895 bool addressedOp = StringTools::containsChar(opName, '.');
2896
2897 if (addressedOp) {
2898 if (opName.substr(0,3) == "_AS") {
2899 int addressSpaceId = -1;
2900 std::string foo;
2901 std::string addressedAS;
2902 std::istringstream iss(opName);
2903 std::getline(iss, foo, '.');
2904 std::getline(iss, addressedAS, '.');
2905 std::getline(iss, opName, '.');
2906 char *end;
2907
2908 AddressSpace* targetAS = NULL;
2909
2910 if (addressedAS.size() && addressedAS[0] == '#') {
2911 addressSpaceId = strtol(addressedAS.c_str()+1, &end, 10);
2912 if (end == addressedAS.c_str()+1) {
2913 std::cerr << "ERROR: Address space id following # not a number '" << addressedAS
2914 << std::endl;
2915 } else {
2916 // find addresspace with given id
2918 for (int i = 0; i < nav.count(); i++) {
2919 AddressSpace* as = nav.item(i);
2920 if (as->hasNumericalId(addressSpaceId)) {
2921 targetAS = as;
2922 break;
2923 }
2924 }
2925 }
2926 } else {
2928 for (int i = 0; i < nav.count(); i++) {
2929 AddressSpace* as = nav.item(i);
2930 if (as->name() == addressedAS) {
2931 targetAS = as;
2932 break;
2933 }
2934 }
2935 }
2936
2937 if (targetAS == NULL) {
2938 std::cerr << "ERROR: Address space '" << addressedAS
2939 << "' not found."
2940 << std::endl;
2941 assert(false);
2942 }
2943
2944 // find function units with given as.
2946 for (int j = 0; j < fuNav.count(); j++) {
2947 const FunctionUnit* fu = fuNav.item(j);
2948 if (fu->addressSpace() == targetAS) {
2949 addressedFUs.push_back(fu->name());
2950 }
2951 }
2952 } else {
2953 // Split the string to get the FU and the operation
2954 std::string addressedFU;
2955
2956 std::istringstream iss(opName);
2957 std::getline(iss, addressedFU, '.');
2958 std::getline(iss, opName, '.');
2959 if (!mach_->functionUnitNavigator().hasItem(addressedFU)) {
2960 std::cerr << "ERROR: Function Unit '" << addressedFU
2961 << "' not found."
2962 << std::endl;
2963 assert(false);
2964 }
2965 addressedFUs.push_back(addressedFU);
2966 }
2967 }
2968
2969 assert(numDefs != numOperands-1 && "No asm string?");
2970 assert(mi->getOperand(numDefs).isSymbol() && "No asm string?");
2971
2972 if (StringTools::containsChar(opName, ' ') ||
2973 StringTools::containsChar(opName, ';') ||
2974 StringTools::containsChar(opName, '>') ||
2975 StringTools::containsChar(opName, '<')) {
2976
2977 std::cerr << "ERROR: Inline assembly not supported!" << std::endl;
2978 assert(false);
2979 }
2980
2982 if (!fu.hasOperation(opName)) {
2983 std::cerr
2984 << "ERROR: Explicitly executed operation '"
2985 << opName << "' does not match any operation definition in OSAL."
2986 << std::endl;
2987 assert(false);
2988 }
2989
2990 HWOperation* op = fu.operation(opName);
2991
2993 std::vector<TTAProgram::Instruction*> operandMoves;
2994 std::vector<TTAProgram::Instruction*> resultMoves;
2997
2998
3000 const Operation& operation = pool.operation(opName.c_str());
3001 int inputOperand = 0;
3002
3003 const MachineFunction& mf = *mi->getParent()->getParent();
3004
3005 // Go through the operands.
3006 unsigned startOp = InlineAsm::MIOp_FirstOperand;
3007 unsigned asmDescOp = InlineAsm::MIOp_FirstOperand;
3008 unsigned clobberOp = InlineAsm::MIOp_FirstOperand-1;
3009 for (unsigned o = startOp; o < mi->getNumOperands(); o++) {
3010 const MachineOperand& mo = mi->getOperand(o);
3011 if (mo.isMetadata()) {
3012 continue;
3013 } else if (o == asmDescOp && mo.isImm()) {
3014 // Skip inline assembly flags.
3015 unsigned flag = mo.getImm();
3016 if (InlineAsm::getKind(flag) == InlineAsm::Kind_Clobber) {
3017 clobberOp = o + 1;
3018 }
3019
3020 asmDescOp += 1 + InlineAsm::getNumOperandRegisters(flag);
3021 continue;
3022 } else if (o == clobberOp) {
3023 if (mf.getRegInfo().isReserved(mo.getReg())) {
3024 std::cerr << "Warning: inline assembly clobbers"
3025 << " reserved register (regNum = " << mo.getReg()
3026 << "), which has undefined behavior."
3027 << std::endl;
3028 }
3029 } else if (!(mo.isReg() || mo.isImm() || mo.isGlobal())) {
3030 // All operands should be immediates or in registers.
3031 // Everything else is ignored.
3032 std::cerr << "Ignoring an operand of " << opName << std::endl;
3033 continue;
3034 }
3035
3036 TTAProgram::Terminal* src = NULL;
3037 TTAProgram::Terminal* dst = NULL;
3038 if (mo.isImm() || mo.isGlobal() || mo.isUse()) {
3039 // implicit usage of whole vector when one element used.
3040 if (useOps.empty()) {
3041 // ignore implicit defs that are too many.
3042 if (mo.isImplicit()) {
3043 continue;
3044 }
3045 std::cerr << std::endl;
3046 std::cerr <<"ERROR: Too many input operands for custom "
3047 << "operation '" << opName << "'." << std::endl;
3048 assert(false);
3049 }
3050 src = createTerminal(mo);
3051 dst = new TTAProgram::TerminalFUPort(*op, (*useOps.begin()));
3052 useOps.erase(useOps.begin());
3053 ++inputOperand;
3054 } else {
3055 if (defOps.empty()) {
3056 // ignore implicit defs that are too many.
3057 if (mo.isImplicit()) {
3058 continue;
3059 }
3060 std::cerr << std::endl;
3061 std::cerr << "ERROR: Too many output operands for custom "
3062 << "operation '" << opName << "'." << std::endl;
3063 assert(false);
3064 }
3065 assert(mo.isReg());
3066 if (mf.getRegInfo().isReserved(mo.getReg())) {
3067 std::cerr << "Warning: inline assembly overwriting"
3068 << " reserved register (regNum = " << mo.getReg()
3069 << ") has undefined behavior."
3070 << std::endl;
3071 }
3072
3073 src = new TTAProgram::TerminalFUPort(*op, (*defOps.begin()));
3074 dst = createTerminal(mo);
3075 defOps.erase(defOps.begin());
3076
3077 }
3078
3079 auto move = createMove(src, dst, bus);
3081 instr->addMove(move);
3082
3083 if (mo.isImm() || mo.isGlobal() || mo.isUse()) {
3084 operandMoves.push_back(instr);
3085
3086 // Custom memory accessing operation? Assume absolute addr for now.
3087 if (operation.operand(inputOperand).isAddress()) {
3088 debugDataToAnnotations(mi, *move);
3089 addPointerAnnotations(mi, *move);
3090 }
3091 } else {
3092 resultMoves.push_back(instr);
3093 }
3094 }
3095
3096 if (!defOps.empty() || !useOps.empty()) {
3097 std::cerr << "ERROR: All operands not defined for custom operation '"
3098 << opName << "'." << std::endl;
3099
3100 std::cerr << "Undefined: " << defOps.size() << " output operands, "
3101 << useOps.size() << " input operands." << std::endl;
3102
3103 abortWithError("Cannot continue");
3104 }
3105
3106 // Return the first instruction of the whole operation.
3107 TTAProgram::Instruction* first = NULL;
3108 if (!operandMoves.empty()) {
3109 first = operandMoves[0];
3110 } else if (!resultMoves.empty()) {
3111 first = resultMoves[0];
3112 } else {
3113 assert(false && "No moves?");
3114 }
3115
3116 for (unsigned i = 0; i < operandMoves.size(); i++) {
3117 proc->add(operandMoves[i]);
3118 if (addressedOp) {
3119 // remove other allowed fu annotations, they are not allowed
3120 operandMoves[i]->move(0).removeAnnotations(
3122
3123 for (unsigned int j = 0; j < addressedFUs.size(); j++) {
3124 TTAProgram::ProgramAnnotation dstCandidate(
3126 addressedFUs[j]);
3127 operandMoves[i]->move(0).addAnnotation(dstCandidate);
3128 }
3129 }
3130 }
3131
3132 for (unsigned i = 0; i < resultMoves.size(); i++) {
3133 proc->add(resultMoves[i]);
3134 if (addressedOp) {
3135 // remove other allowed fu annotations, they are not allowed
3136 resultMoves[i]->move(0).removeAnnotations(
3138
3139 for (unsigned int j = 0; j < addressedFUs.size(); j++) {
3140 TTAProgram::ProgramAnnotation srcCandidate(
3142 addressedFUs[j]);
3143 resultMoves[i]->move(0).addAnnotation(srcCandidate);
3144 }
3145 }
3146 }
3147 return first;
3148}
static bool containsChar(const std::string &source, char ch, bool caseSensitive=true)
OperandSet writtenOperands(int cycle) const
OperandSet readOperands(int cycle) const
std::set< int > OperandSet
Set for operand indexes.
ExecutionPipeline * pipeline() const
virtual TTAMachine::HWOperation * operation(const std::string &name) const
virtual bool hasOperation(const std::string &name) const
UniversalFunctionUnit & universalFunctionUnit() const
TTAProgram::Instruction * emitSpecialInlineAsm(const std::string op, const MachineInstr *mi, TTAProgram::CodeSnippet *proc)

References abortWithError, TTAProgram::CodeSnippet::add(), TTAProgram::Instruction::addMove(), addPointerAnnotations(), TTAMachine::FunctionUnit::addressSpace(), addressSpaceId(), TTAMachine::Machine::addressSpaceNavigator(), TTAProgram::ProgramAnnotation::ANN_ALLOWED_UNIT_DST, TTAProgram::ProgramAnnotation::ANN_ALLOWED_UNIT_SRC, assert, StringTools::containsChar(), TTAMachine::Machine::Navigator< ComponentType >::count(), createMove(), createTerminal(), debugDataToAnnotations(), emitSpecialInlineAsm(), TTAMachine::Machine::functionUnitNavigator(), TTAMachine::Machine::Navigator< ComponentType >::hasItem(), TTAMachine::AddressSpace::hasNumericalId(), UniversalFunctionUnit::hasOperation(), UniversalMachine::instance(), Operand::isAddress(), TTAMachine::Machine::Navigator< ComponentType >::item(), mach_, TTAMachine::Component::name(), Operation::operand(), UniversalFunctionUnit::operation(), TTAMachine::HWOperation::pipeline(), TTAMachine::ExecutionPipeline::readOperands(), UniversalMachine::universalBus(), UniversalMachine::universalFunctionUnit(), and TTAMachine::ExecutionPipeline::writtenOperands().

Referenced by emitInstruction().

Here is the call graph for this function:

◆ emitReadSP()

TTAProgram::Instruction * LLVMTCEBuilder::emitReadSP ( const MachineInstr *  mi,
TTAProgram::CodeSnippet proc 
)
private

Emits moves to read the stack pointer value.

Definition at line 3211 of file LLVMTCEBuilder.cc.

3212 {
3213
3214 if (mi->getNumOperands() != 5) {
3216 "ERROR: wrong number of operands in \".read_sp\"");
3217 }
3218
3219 // Get the stack pointer. It will be used as index into
3220 // the buffer.
3221 unsigned spDRN = spDRegNum();
3222 TCEString sp = (boost::format("%s.%d") %
3223 registerFileName(spDRN) %
3224 registerIndex(spDRN)).str();
3225
3226 // We need to know where current procedure ends to
3227 // be able to return first generated instruction.
3228 TTAProgram::Instruction& lastInstruction =
3229 proc->lastInstruction();
3230
3231 CodeGenerator codeGenerator(*mach_);
3232
3233 TTAProgram::Terminal* srcTerminal =
3234 codeGenerator.createTerminalRegister(sp, false);
3235
3236 const MachineOperand& dest = mi->getOperand(3);
3237 // Save SP at the first position in the buffer.
3238 TTAProgram::Terminal* destTerminal = createTerminal(dest);
3239
3240 codeGenerator.addMoveToProcedure(*proc, srcTerminal, destTerminal);
3241 return &(proc->nextInstruction(lastInstruction));
3242}
virtual Instruction & nextInstruction(const Instruction &ins) const

References abortWithError, TTAProgram::CodeGenerator::addMoveToProcedure(), createTerminal(), TTAProgram::CodeGenerator::createTerminalRegister(), TTAProgram::CodeSnippet::lastInstruction(), mach_, TTAProgram::CodeSnippet::nextInstruction(), registerFileName(), registerIndex(), and spDRegNum().

Referenced by emitSpecialInlineAsm().

Here is the call graph for this function:

◆ emitRemaingingBrach()

TTAProgram::Instruction * LLVMTCEBuilder::emitRemaingingBrach ( TCEString  opName,
const MachineInstr *  mi,
TTAProgram::CodeSnippet proc 
)
private

Definition at line 1769 of file LLVMTCEBuilder.cc.

1770 {
1771
1772 bool inverted = (opName[0] == '!');
1773 opName = opName.substr(1); // drop the inversion char
1774 const HWOperation& op = getHWOperation(opName);
1775
1777 const Operation& operation = pool.operation(opName.c_str());
1779
1780 ProgramOperationPtr po(new ProgramOperation(operation, mi));
1781 const MachineOperand& mo = mi->getOperand(2);
1784
1785 RegisterGuard* bypassRegGuard =
1786 new RegisterGuard(inverted,
1787 UniversalMachine::instance().booleanRegisterFile(),
1788 0, nullptr);
1789
1790 auto move = createMove(src, dst, bus, (new TTAProgram::MoveGuard(*bypassRegGuard)));
1792 instr->addMove(move);
1793 proc->add(instr);
1794 createMoveNode(po, move, true);
1795 return instr;
1796}

References TTAProgram::CodeSnippet::add(), TTAProgram::Instruction::addMove(), createMove(), createMoveNode(), createTerminal(), getHWOperation(), UniversalMachine::instance(), and UniversalMachine::universalBus().

Referenced by emitInstruction().

Here is the call graph for this function:

◆ emitReturn()

TTAProgram::Instruction * LLVMTCEBuilder::emitReturn ( const MachineInstr *  mi,
TTAProgram::CodeSnippet proc 
)
private

Creates POM instructions for a return.

Parameters
miReturn machine instruction.
procPOM procedure to add the return to.
Returns
First of the emitted POM instructions.

Definition at line 2534 of file LLVMTCEBuilder.cc.

2535 {
2536
2539 *UniversalMachine::instance().controlUnit()->returnAddressPort());
2540
2543
2545 const Operation& operation = pool.operation("jump");
2546
2548 auto move = createMove(src, dst, bus);
2550 instr->addMove(move);
2551 proc->add(instr);
2552 ProgramOperationPtr po(new ProgramOperation(operation, mi));
2553 createMoveNode(po, move, true);
2554 return instr;
2555}
virtual HWOperation * operation(const std::string &name) const
virtual ControlUnit * controlUnit() const
Definition Machine.cc:345

References TTAProgram::CodeSnippet::add(), TTAProgram::Instruction::addMove(), TTAMachine::Machine::controlUnit(), createMove(), createMoveNode(), UniversalMachine::instance(), TTAMachine::FunctionUnit::operation(), and UniversalMachine::universalBus().

Referenced by emitInstruction().

Here is the call graph for this function:

◆ emitReturnTo()

TTAProgram::Instruction * LLVMTCEBuilder::emitReturnTo ( const MachineInstr *  mi,
TTAProgram::CodeSnippet proc 
)
private

Emits moves that overwrite the RA and return to that address.

Definition at line 3248 of file LLVMTCEBuilder.cc.

3249 {
3250
3251 if (mi->getNumOperands() != 5) {
3253 "ERROR: wrong number of operands in \".return_to\"");
3254 }
3255
3256 // We need to know where current procedure ends to
3257 // be able to return first generated instruction.
3258 TTAProgram::Instruction& lastInstruction = proc->lastInstruction();
3259
3260 CodeGenerator codeGenerator(*mach_);
3261 // the source from which to overwrite RA
3262 const MachineOperand& src = mi->getOperand(3);
3263
3264 /* src -> RA */
3265 codeGenerator.addMoveToProcedure(
3266 *proc, createTerminal(src),
3267 codeGenerator.createTerminalRegister("RA", false));
3268 /* RA -> JUMP.1 */
3269 codeGenerator.registerJump(*proc, "RA");
3270
3271 return &(proc->nextInstruction(lastInstruction));
3272}

References abortWithError, TTAProgram::CodeGenerator::addMoveToProcedure(), createTerminal(), TTAProgram::CodeGenerator::createTerminalRegister(), TTAProgram::CodeSnippet::lastInstruction(), mach_, TTAProgram::CodeSnippet::nextInstruction(), and TTAProgram::CodeGenerator::registerJump().

Referenced by emitSpecialInlineAsm().

Here is the call graph for this function:

◆ emitSelect()

TTAProgram::Instruction * LLVMTCEBuilder::emitSelect ( const MachineInstr *  mi,
TTAProgram::CodeSnippet proc 
)
private

Creates POM instructions for a select.

Parameters
miselect machine instruction.
procPOM procedure to add the select to.
Returns
First of the emitted POM instructions.

Definition at line 2565 of file LLVMTCEBuilder.cc.

2566 {
2567
2568// 0 = dest?
2569
2570 const MachineOperand& guardMo = mi->getOperand(1);
2571
2572 // Create move from the condition operand register to bool register
2573 // which is used by the guard.
2574 TTAProgram::Terminal *guardTerminal = createTerminal(guardMo);
2575
2576 assert(guardTerminal != NULL);
2577
2578 TTAProgram::Terminal* dstT = createTerminal(mi->getOperand(0));
2579 TTAProgram::Terminal* dstF = createTerminal(mi->getOperand(0));
2580 TTAProgram::Terminal* srcT = createTerminal(mi->getOperand(2));
2581 TTAProgram::Terminal* srcF = createTerminal(mi->getOperand(3));
2582
2584 TTAProgram::Instruction *firstIns = NULL;
2585
2586 // do no create X -> X moves.
2587 if (dstT->equals(*srcT)) {
2588 if (dstT->equals(*srcF)) {
2589 std::cerr << "Empty select!" << std::endl;
2590 return NULL;
2591 }
2592 delete srcT;
2593 delete dstT;
2594 } else {
2595 TTAProgram::MoveGuard* trueGuard = createGuard(guardTerminal, true);
2596 assert(trueGuard != NULL);
2597 auto trueMove = createMove(srcT, dstT, bus, trueGuard);
2599 trueIns->addMove(trueMove);
2600 proc->add(trueIns);
2601 firstIns = trueIns;
2602 }
2603
2604 // do no create X -> X moves.
2605 if (dstF->equals(*srcF)) {
2606 delete srcF;
2607 delete dstF;
2608 } else {
2609 TTAProgram::MoveGuard* falseGuard = createGuard(guardTerminal, false);
2610 assert(falseGuard != NULL);
2611 auto falseMove = createMove(srcF, dstF, bus, falseGuard);
2613 falseIns->addMove(falseMove);
2614 proc->add(falseIns);
2615 if (firstIns == NULL) {
2616 firstIns = falseIns;
2617 }
2618 }
2619
2620 // guardTerminal was just temporary used as helper when creating guards.
2621 delete guardTerminal;
2622
2623 assert(firstIns != NULL);
2624 return firstIns;
2625}
virtual bool equals(const Terminal &other) const =0

References TTAProgram::CodeSnippet::add(), TTAProgram::Instruction::addMove(), assert, createGuard(), createMove(), createTerminal(), TTAProgram::Terminal::equals(), UniversalMachine::instance(), and UniversalMachine::universalBus().

Referenced by emitInstruction().

Here is the call graph for this function:

◆ emitSetjmp()

TTAProgram::Instruction * LLVMTCEBuilder::emitSetjmp ( const MachineInstr *  mi,
TTAProgram::CodeSnippet proc 
)
private

Constructs moves for ".setjmp"

Parameters
miMachine instruction including the inline asm.
procTTA procedure to emit moves into.
Returns
First instruction in emmited block.

Definition at line 3379 of file LLVMTCEBuilder.cc.

3380 {
3381
3382 if (mi->getNumOperands() != 7) {
3383 std::cerr << "ERROR: wrong number of operands in "".setjmp"""
3384 << std::endl;
3385 assert(false);
3386 }
3387 const MachineOperand& val = mi->getOperand(3);
3388 const MachineOperand& env = mi->getOperand(5);
3389 // Get the stack pointer. It will be used as index into
3390 // the buffer.
3391 unsigned spDRN = spDRegNum();
3392 TCEString sp = (boost::format("%s.%d") %
3393 registerFileName(spDRN) %
3394 registerIndex(spDRN)).str();
3395
3396 // We need to know where current procedure ends to
3397 // be able to return first generated instruction.
3398 int oldSize = proc->instructionCount();
3399
3400 CodeGenerator codeGenerator(*mach_);
3401
3402 // Save SP at the first position in the buffer.
3403 TTAProgram::Terminal* buffer = createTerminal(env);
3404 codeGenerator.storeToAddress(*proc, buffer, sp);
3405
3406 // Now we can scratch the stack pointer.
3407
3408 // First thing we need is to store buffer address in SP.
3409 buffer = createTerminal(env);
3410 TTAProgram::Terminal* spTerminal =
3411 codeGenerator.createTerminalRegister(sp, false);
3412
3413 codeGenerator.addMoveToProcedure(*proc, buffer, spTerminal);
3414
3415 // Increment index to jump over the place where SP was
3416 // stored.
3417 codeGenerator.incrementStackPointer(*proc, sp);
3418
3419 // Save RA first (special register).
3420 codeGenerator.pushRegisterToStack(*proc, sp, "RA");
3421
3422 // Now save the desired return value.
3423 SimValue immVal(mach_->is64bit() ? 64 : 32);
3424 immVal = 0;
3425 TTAProgram::TerminalImmediate *immTerminal =
3427 codeGenerator.pushToStack(*proc, sp, immTerminal);
3428
3429 // Now we can save every register there.
3432
3433 int buffer_words = 0;
3434
3435 for (int i = 0; i < nav.count(); i++) {
3436 const TTAMachine::RegisterFile& rf = *nav.item(i);
3437 for (int j = 0; j < rf.numberOfRegisters(); j++) {
3438 TCEString reg =
3439 (boost::format("%s.%d") % rf.name() % j).str();
3440 if (reg != sp) { // sp already saved, ignore it.
3441 codeGenerator.pushRegisterToStack(*proc, sp, reg);
3442 buffer_words++;
3443 }
3444 }
3445 }
3446
3447 // Save the setjmp return point.
3448 TTAProgram::Instruction* returnInstruction =
3451
3452 TTAProgram::InstructionReference returnReference =
3454 *returnInstruction);
3455
3456 codeGenerator.pushInstructionReferenceToStack(*proc, sp, returnReference);
3457
3458 codeGenerator.decrementStackPointer(*proc, sp);
3459
3460 proc->add(returnInstruction);
3461
3462 // Move back the stored registers.
3463 for (int i = 0; i < buffer_words; i++)
3464 codeGenerator.decrementStackPointer(*proc, sp);
3465
3466 // Get return value.
3468 codeGenerator.popFromStack(*proc, sp, rv);
3469
3470 // Restore original RA.
3471 codeGenerator.popRegisterFromStack(*proc, sp, "RA");
3472
3473 // Restore SP from first position in the buffer.
3474 codeGenerator.popRegisterFromStack(*proc, sp, sp);
3475
3476 return &(proc->instructionAtIndex(oldSize));
3477}

References TTAProgram::CodeSnippet::add(), TTAProgram::CodeGenerator::addMoveToProcedure(), assert, TTAMachine::Machine::Navigator< ComponentType >::count(), TTAProgram::InstructionReferenceManager::createReference(), createTerminal(), TTAProgram::CodeGenerator::createTerminalRegister(), TTAProgram::CodeGenerator::decrementStackPointer(), TTAProgram::CodeGenerator::incrementStackPointer(), TTAMachine::NullInstructionTemplate::instance(), TTAProgram::CodeSnippet::instructionAtIndex(), TTAProgram::CodeSnippet::instructionCount(), TTAProgram::Program::instructionReferenceManager(), TTAMachine::Machine::is64bit(), TTAMachine::Machine::Navigator< ComponentType >::item(), mach_, TTAMachine::Component::name(), TTAMachine::BaseRegisterFile::numberOfRegisters(), TTAProgram::CodeGenerator::popFromStack(), TTAProgram::CodeGenerator::popRegisterFromStack(), prog_, TTAProgram::CodeGenerator::pushInstructionReferenceToStack(), TTAProgram::CodeGenerator::pushRegisterToStack(), TTAProgram::CodeGenerator::pushToStack(), registerFileName(), TTAMachine::Machine::registerFileNavigator(), registerIndex(), spDRegNum(), and TTAProgram::CodeGenerator::storeToAddress().

Referenced by emitSpecialInlineAsm().

Here is the call graph for this function:

◆ emitSpecialInlineAsm()

TTAProgram::Instruction * LLVMTCEBuilder::emitSpecialInlineAsm ( const std::string  op,
const MachineInstr *  mi,
TTAProgram::CodeSnippet proc 
)
private

Constructs moves for architecture-dependant special asm.

Parameters
opAssembly instruction string.
miMachine instruction including the inline asm.
procTTA procedure to emit moves into.
Returns
First instruction in emitted block.

Definition at line 3160 of file LLVMTCEBuilder.cc.

3162 {
3163
3164 assert(op[0] == '.');
3165
3166 TCEString subOp(std::string(op, 1, op.length() - 1));
3167
3168 if (subOp == "setjmp")
3169 return emitSetjmp(mi, proc);
3170
3171 if (subOp == "longjmp")
3172 return emitLongjmp(mi, proc);
3173
3174 if (subOp == "call_global_ctors")
3175 return emitGlobalXXtructorCalls(mi, proc, true);
3176
3177 if (subOp == "call_global_dtors")
3178 return emitGlobalXXtructorCalls(mi, proc, false);
3179
3180 if (subOp.startsWith("read_sp "))
3181 return emitReadSP(mi, proc);
3182
3183 if (subOp.startsWith("write_sp "))
3184 return emitWriteSP(mi, proc);
3185
3186 if (subOp.startsWith("return_to "))
3187 return emitReturnTo(mi, proc);
3188
3189 // Just strip the pregion markers for now, later on, use it in the
3190 // alias analysis.
3191 if (subOp.startsWith("pregion_start.") || subOp.startsWith("pregion_end"))
3192 return NULL;
3193
3194 // memory_category pseudo asms can be used to define
3195 // categories for different pointers. They mark those
3196 // pointers to alias only with others pointers in the
3197 // same category.
3198 if (subOp.startsWith("pointer_category"))
3199 return handleMemoryCategoryInfo(mi, proc);
3200
3201 debugLog(subOp);
3202 abortWithError("Undetected special inline asm.");
3203
3204 return NULL;
3205}
#define debugLog(text)
TTAProgram::Instruction * handleMemoryCategoryInfo(const MachineInstr *mi, TTAProgram::CodeSnippet *proc)
TTAProgram::Instruction * emitReturnTo(const MachineInstr *mi, TTAProgram::CodeSnippet *proc)
TTAProgram::Instruction * emitSetjmp(const MachineInstr *mi, TTAProgram::CodeSnippet *proc)
TTAProgram::Instruction * emitGlobalXXtructorCalls(const MachineInstr *mi, TTAProgram::CodeSnippet *proc, bool constructors)
TTAProgram::Instruction * emitWriteSP(const MachineInstr *mi, TTAProgram::CodeSnippet *proc)
TTAProgram::Instruction * emitLongjmp(const MachineInstr *mi, TTAProgram::CodeSnippet *proc)
TTAProgram::Instruction * emitReadSP(const MachineInstr *mi, TTAProgram::CodeSnippet *proc)

References abortWithError, assert, debugLog, emitGlobalXXtructorCalls(), emitLongjmp(), emitReadSP(), emitReturnTo(), emitSetjmp(), emitWriteSP(), handleMemoryCategoryInfo(), and TCEString::startsWith().

Referenced by emitOperationMacro().

Here is the call graph for this function:

◆ emitSPInitialization() [1/2]

void LLVMTCEBuilder::emitSPInitialization ( )
protectedvirtual

Emit stack pointer initialization move to the begining of the program.

Reimplemented in llvm::LLVMTCEIRBuilder.

Definition at line 2673 of file LLVMTCEBuilder.cc.

2673 {
2675
2676 TTAProgram::Procedure& proc =
2677 dynamic_cast<TTAProgram::Procedure&>(first.parent());
2678
2680}
CodeSnippet & parent() const
Instruction & firstInstruction() const
Definition Program.cc:353

References emitSPInitialization(), TTAProgram::Program::firstInstruction(), TTAProgram::Instruction::parent(), and prog_.

Referenced by llvm::LLVMTCEIRBuilder::buildTCECFG(), doFinalization(), and emitSPInitialization().

Here is the call graph for this function:

◆ emitSPInitialization() [2/2]

void LLVMTCEBuilder::emitSPInitialization ( TTAProgram::CodeSnippet target)
protected

Definition at line 2683 of file LLVMTCEBuilder.cc.

2683 {
2684
2685 unsigned spDRN = spDRegNum();
2686 std::string spRfName = registerFileName(spDRN);
2687 int idx = registerIndex(spDRN);
2689 const RegisterFile* rf = mach_->registerFileNavigator().item(spRfName);
2690 assert(idx >= 0 && idx < rf->size());
2691 const RFPort* port = NULL;
2692 for (int i = 0; i < rf->portCount(); i++) {
2693 if (rf->port(i)->isOutput()) {
2694 port = rf->port(i);
2695 break;
2696 }
2697 }
2698 assert(port != NULL);
2700 TTAProgram::TerminalRegister(*port, idx);
2701
2702 unsigned ival = initialStackPointerValue_;
2703
2704 const TCETargetMachine* tm = dynamic_cast<const TCETargetMachine*>(tm_);
2705 assert(tm != NULL);
2706 unsigned stackAlignment = tm->stackAlignment();
2707 unsigned mask = 0xffffffff;
2708
2709 while (stackAlignment > 1) {
2710 mask = mask << 1;
2711 stackAlignment = stackAlignment >> 1;
2712 }
2713
2714 if (initialStackPointerValue_ == 0 ||
2715 initialStackPointerValue_ > (addressSpaceById(0).end() & mask)) {
2716 ival = addressSpaceById(0).end() & mask;
2717 }
2718
2719 SimValue val(ival, mach_->is64bit() ? 64 : 32);
2725 auto move = createMove(src, dst, bus);
2726 TTAProgram::Instruction* spInitInst =
2728 spInitInst->addMove(move);
2729 spInit->add(spInitInst);
2730 } else {
2731 // Immediate is not enough for the initial stack pointer value, //
2732 // must load it from memory. //
2733
2734 // Data definition for initial stack pointer value stored at zero //
2735 // address //
2736
2737 // FIXME: Assuming 8bit MAU.
2738 // TODO: FIXME: Also assumes 32-bit architecture!
2739 union {
2740 unsigned i;
2741 char bytes[4];
2742 } u;
2743
2744 u.i = ival;
2745
2746 std::vector<MinimumAddressableUnit> spmaus;
2747 unsigned nMaus = sizeof(unsigned);
2748 if (!mach_->isLittleEndian()) {
2749 for (unsigned i = 0; i < nMaus; i++) {
2750 spmaus.push_back(u.bytes[nMaus-i-1]);
2751 }
2752 } else {
2753 for (unsigned i = 0; i < nMaus; i++) {
2754 spmaus.push_back(u.bytes[i]);
2755 }
2756 }
2759 TTAProgram::Address zeroAddr(0, aSpace);
2761 zeroAddr, spmaus, mach_->isLittleEndian()));
2762
2763 // Emit load for stack pointer //
2764 CodeGenerator codegen(*mach_);
2766 new TTAProgram::TerminalAddress(SimValue(0, 32), aSpace);
2767
2768 createSPInitLoad(*spInit, *zeroImm, *dst);
2769 }
2770
2771 if (target.instructionCount() > 0) {
2772 TTAProgram::Instruction& first = target.firstInstruction();
2773 target.insertBefore(first, spInit);
2776 first, spInit->firstInstruction());
2777 }
2778 } else {
2779 target.append(spInit);
2780 }
2781}
static bool canEncodeImmediateInteger(const TTAMachine::Machine &mach, int64_t imm, unsigned destWidth=UINT_MAX)
virtual ULongWord end() const
virtual Instruction & firstInstruction() const
virtual void append(const CodeSnippet &cs)
virtual void insertBefore(const Instruction &pos, Instruction *ins)
void replace(Instruction &insA, Instruction &insB)
void createSPInitLoad(TTAProgram::CodeSnippet &target, TTAProgram::Terminal &src, TTAProgram::Terminal &dst)
unsigned stackAlignment() const

References TTAProgram::DataMemory::addDataDefinition(), TTAProgram::Instruction::addMove(), addressSpaceById(), TTAProgram::CodeSnippet::append(), assert, MachineInfo::canEncodeImmediateInteger(), createMove(), createSPInitLoad(), dataMemoryForAddressSpace(), TTAMachine::AddressSpace::end(), TTAProgram::CodeSnippet::firstInstruction(), TTAMachine::Machine::Navigator< ComponentType >::hasItem(), TTAProgram::InstructionReferenceManager::hasReference(), initialStackPointerValue_, TTAProgram::CodeSnippet::insertBefore(), UniversalMachine::instance(), TTAProgram::CodeSnippet::instructionCount(), TTAProgram::Program::instructionReferenceManager(), TTAMachine::Machine::is64bit(), TTAMachine::Machine::isLittleEndian(), TTAMachine::Port::isOutput(), TTAMachine::Machine::Navigator< ComponentType >::item(), mach_, TTAMachine::BaseRegisterFile::port(), TTAMachine::Unit::portCount(), prog_, registerFileName(), TTAMachine::Machine::registerFileNavigator(), registerIndex(), TTAProgram::InstructionReferenceManager::replace(), spDRegNum(), llvm::TCETargetMachine::stackAlignment(), tm_, and UniversalMachine::universalBus().

Here is the call graph for this function:

◆ emitStore()

TTAProgram::Instruction * llvm::LLVMTCEBuilder::emitStore ( const MachineInstr *  mi,
TTAProgram::CodeSnippet proc 
)
private

◆ emitWriteSP()

TTAProgram::Instruction * LLVMTCEBuilder::emitWriteSP ( const MachineInstr *  mi,
TTAProgram::CodeSnippet proc 
)
private

Emits moves to write the stack pointer value.

Definition at line 3279 of file LLVMTCEBuilder.cc.

3280 {
3281
3282 if (mi->getNumOperands() != 5) {
3284 << "got " << mi->getNumOperands() << " operands" << std::endl;
3286 "ERROR: wrong number of operands in \".write_sp\"");
3287 }
3288
3289 const TCETargetMachine* tm = dynamic_cast<const TCETargetMachine*>(tm_);
3290 assert(tm_ != NULL);
3291 // Get the stack pointer. It will be used as index into
3292 // the buffer.
3293 unsigned spDRN = tm->spDRegNum();
3294 TCEString sp = (boost::format("%s.%d") %
3295 tm->rfName(spDRN) %
3296 tm->registerIndex(spDRN)).str();
3297
3298 // We need to know where current procedure ends to
3299 // be able to return first generated instruction.
3300 TTAProgram::Instruction& lastInstruction =
3301 proc->lastInstruction();
3302
3303 CodeGenerator codeGenerator(*mach_);
3304
3305 TTAProgram::Terminal* destTerminal =
3306 codeGenerator.createTerminalRegister(sp, false);
3307
3308 const MachineOperand& src = mi->getOperand(3);
3309 TTAProgram::Terminal* srcTerminal = createTerminal(src);
3310
3311 codeGenerator.addMoveToProcedure(*proc, srcTerminal, destTerminal);
3312 return &(proc->nextInstruction(lastInstruction));
3313}
std::string rfName(unsigned dwarfRegNum) const
unsigned registerIndex(unsigned dwarfRegNum) const

References abortWithError, TTAProgram::CodeGenerator::addMoveToProcedure(), assert, createTerminal(), TTAProgram::CodeGenerator::createTerminalRegister(), TTAProgram::CodeSnippet::lastInstruction(), Application::logStream(), mach_, TTAProgram::CodeSnippet::nextInstruction(), llvm::TCETargetMachine::registerIndex(), llvm::TCETargetMachine::rfName(), llvm::TCETargetMachine::spDRegNum(), and tm_.

Referenced by emitSpecialInlineAsm().

Here is the call graph for this function:

◆ firstInstructionOfBasicBlock()

TTAProgram::Instruction * llvm::LLVMTCEBuilder::firstInstructionOfBasicBlock ( const llvm::BasicBlock *  bb)
inline

Definition at line 119 of file LLVMTCEBuilder.hh.

120 {
121 return bbIndex_[bb];
122 }
std::map< const llvm::BasicBlock *, TTAProgram::Instruction * > bbIndex_
Basic Block -> first instruction in the BB map.

References bbIndex_.

◆ fixProgramOperationReferences()

void LLVMTCEBuilder::fixProgramOperationReferences ( )
protected

Fixes the symbolic ProgramOperation references to point to the now created real ProgramOperations.

Assumes the POs are found in the label index.

Definition at line 2280 of file LLVMTCEBuilder.cc.

2280 {
2281 for (std::set<TTAProgram::TerminalProgramOperation*>::const_iterator i =
2282 symbolicPORefs_.begin(); i != symbolicPORefs_.end(); ++i) {
2284 if (term->isProgramOperationKnown()) continue;
2286 assert(po.get() != NULL);
2287 term->setProgramOperation(po);
2288 }
2289}
void setProgramOperation(ProgramOperationPtr po)

References assert, TTAProgram::TerminalProgramOperation::isProgramOperationKnown(), TTAProgram::TerminalProgramOperation::label(), labeledPOs_, TTAProgram::TerminalProgramOperation::setProgramOperation(), and symbolicPORefs_.

Referenced by llvm::LLVMTCEIRBuilder::buildTCECFG().

Here is the call graph for this function:

◆ getAnalysisUsage()

virtual void llvm::LLVMTCEBuilder::getAnalysisUsage ( AnalysisUsage &  AU) const
inlinevirtual

Reimplemented in llvm::LLVMTCEIRBuilder.

Definition at line 125 of file LLVMTCEBuilder.hh.

125 {
126 AU.addRequired<AAResultsWrapperPass>();
127 AU.addRequired<MachineDCE>();
128 AU.addPreserved<MachineDCE>();
129 MachineFunctionPass::getAnalysisUsage(AU);
130 }

Referenced by llvm::LLVMTCEIRBuilder::getAnalysisUsage().

◆ getAsmString()

std::string llvm::LLVMTCEBuilder::getAsmString ( const MachineInstr &  mi) const
private

◆ getHWOperation()

const TTAMachine::HWOperation & LLVMTCEBuilder::getHWOperation ( std::string  opName)
protected

Definition at line 1292 of file LLVMTCEBuilder.cc.

1292 {
1293 const TTAMachine::FunctionUnit* fu = NULL;
1294
1295 if (UniversalMachine::instance().controlUnit()->hasOperation(opName)) {
1297 } else if (UniversalMachine::instance().universalFunctionUnit().
1298 hasOperation(opName)) {
1300 } else {
1302 TCEString("ERROR: Operation '") + opName +
1303 "' not found in the machine.");
1304 }
1305
1306 // Check that the target machine supports this instruction.
1307 if (opset_.find(StringTools::stringToLower(opName)) == opset_.end()) {
1308 std::cerr << "ERROR: Operation '" << opName
1309 << "' is required by the program but not found "
1310 << "in the machine." << std::endl;
1311 abortWithError("Cannot proceed.");
1312 }
1313 return *fu->operation(opName);
1314}
static std::string stringToLower(const std::string &source)
std::set< std::string > opset_
The operations supported by the current target machine.

References abortWithError, TTAMachine::Machine::controlUnit(), UniversalMachine::instance(), TTAMachine::FunctionUnit::operation(), opset_, StringTools::stringToLower(), and UniversalMachine::universalFunctionUnit().

Referenced by emitComparisonForBranch(), emitInstruction(), emitMove(), and emitRemaingingBrach().

Here is the call graph for this function:

◆ handleMemoryCategoryInfo()

TTAProgram::Instruction * LLVMTCEBuilder::handleMemoryCategoryInfo ( const MachineInstr *  mi,
TTAProgram::CodeSnippet proc 
)
private

Handles the .pointer_category pseudo assembler instruction.

First argument is a string defining the category, second refers to the pointer.

Definition at line 3322 of file LLVMTCEBuilder.cc.

3323 {
3324
3325 if (mi->getNumOperands() != 6) {
3327 << "got " << mi->getNumOperands() << " operands" << std::endl;
3329 "ERROR: wrong number of operands in \".pointer_category\"");
3330 }
3331
3332 TTAProgram::Instruction& lastInstruction =
3333 proc->lastInstruction();
3334
3335 CodeGenerator codeGenerator(*mach_);
3336
3337 TTAProgram::Terminal* srcTerminal =
3338 createTerminal(mi->getOperand(5));
3339
3340 TTAProgram::Terminal* dstTerminal =
3341 createTerminal(mi->getOperand(3));
3342 codeGenerator.addMoveToProcedure(*proc, srcTerminal, dstTerminal);
3343 return &(proc->nextInstruction(lastInstruction));
3344}

References abortWithError, TTAProgram::CodeGenerator::addMoveToProcedure(), createTerminal(), TTAProgram::CodeSnippet::lastInstruction(), Application::logStream(), mach_, and TTAProgram::CodeSnippet::nextInstruction().

Referenced by emitSpecialInlineAsm().

Here is the call graph for this function:

◆ hasAmbiguousASpaceRefs()

bool LLVMTCEBuilder::hasAmbiguousASpaceRefs ( const TTAProgram::Instruction instr) const
protected

Checks that the potential memory operations triggered in the given unscheduled instruction (with exactly one move) have unambiguous address space.

This should be called as a sanity check for instructions in a program (and a machine) with multiple address spaces. Returns true in case the instruction has at least one move that refers to memory without the address space information being unambiguous in the currently targeted machine.

Definition at line 1263 of file LLVMTCEBuilder.cc.

1264 {
1265
1266 const TTAProgram::Move& m = instr.move(0);
1267 const TTAProgram::Terminal& t = m.destination();
1268 if (t.isFUPort() && !t.isRA() &&
1270 !m.hasAnnotations(
1272
1273 TCEString opName =
1274 dynamic_cast<const TTAProgram::TerminalFUPort&>(t).
1275 hwOperation()->name();
1276 int numberOfPotentialFUs = 0;
1279 for (int i = 0; i < fuNav.count(); i++) {
1280 const TTAMachine::FunctionUnit& fu = *fuNav.item(i);
1281 if (fu.hasOperation(opName)) numberOfPotentialFUs++;
1282 }
1283
1284 if (numberOfPotentialFUs > 1) {
1285 return true;
1286 }
1287 }
1288 return false;
1289}
bool hasAnnotations(ProgramAnnotation::Id id=ProgramAnnotation::ANN_UNDEF_ID) const
virtual bool isRA() const
Definition Terminal.cc:129
virtual Operation & hintOperation() const
Definition Terminal.cc:341
virtual int operationIndex() const
Definition Terminal.cc:364

References TTAProgram::ProgramAnnotation::ANN_ALLOWED_UNIT_DST, TTAMachine::Machine::Navigator< ComponentType >::count(), TTAProgram::Move::destination(), TTAMachine::Machine::functionUnitNavigator(), TTAProgram::AnnotatedInstructionElement::hasAnnotations(), TTAMachine::FunctionUnit::hasOperation(), TTAProgram::Terminal::hintOperation(), Operand::isAddress(), TTAProgram::Terminal::isFUPort(), TTAProgram::Terminal::isRA(), TTAMachine::Machine::Navigator< ComponentType >::item(), mach_, TTAProgram::Instruction::move(), Operation::operand(), and TTAProgram::Terminal::operationIndex().

Referenced by writeMachineFunction().

Here is the call graph for this function:

◆ initDataSections()

void LLVMTCEBuilder::initDataSections ( )
protected

Initializes the data sections of the POM.

Can be called multiple times. Doesn't do anything after the first successful call.

Definition at line 210 of file LLVMTCEBuilder.cc.

210 {
211
212 if (dataInitialized_)
213 return;
214
215 dataInitialized_ = true;
216
217 assert(mach_ != NULL);
218 assert(tm_ != NULL);
219 assert(mod_ != NULL);
220
221 if (prog_ != NULL) {
222 delete prog_;
223 prog_ = NULL;
224 }
225
226 // List of supported operations.
227 opset_.insert("jump");
228 opset_.insert("call");
231
232 for (int i = 0;i < fuNav.count(); i++) {
233 const FunctionUnit& fu = *fuNav.item(i);
234 for (int o = 0; o < fu.operationCount(); o++) {
236 }
237 }
238
239 const auto& cu = *mach_->controlUnit();
240 for (int o = 0; o < cu.operationCount(); o++) {
241 opset_.insert(StringTools::stringToLower(cu.operation(o)->name()));
242 }
243
244 // Set GCU address space as the instruction address space.
245 if (mach_->controlUnit() == NULL) {
246 std::cerr << "ERROR: No control unit in the target machine!"
247 << std::endl;
248
249 assert(false);
250 }
251
253 if (instrAddressSpace_ == NULL) {
254 std::cerr << "ERROR: Address space set for the control unit in the "
255 << "target machine."
256 << std::endl;
257
258 assert(false);
259 }
260
261 // FIXME: data address space
264
265 multiDataMemMachine_ = nav.count() > 2;
267
268 for (int i = 0; i < nav.count(); i++) {
269 if (nav.item(i) != instrAddressSpace_) {
270 if (!multiDataMemMachine_ || nav.item(i)->hasNumericalId(0)) {
272 break;
273 }
274 }
275 }
276
277 if (defaultDataAddressSpace_ == NULL) {
278 std::cerr << "ERROR: Unable to determine the default data address space."
279 << std::endl;
280 abort();
281 } else {
284 << "using '" << defaultDataAddressSpace_->name()
285 << "' as the default data address space"
286 << std::endl;
287 }
288 }
289
291 mang_ = new Mangler();
292
293 const TCETargetMachine* tm = dynamic_cast<const TCETargetMachine*>(tm_);
294 assert(tm != NULL);
295
297
298 // Global variables.
299 for (Module::const_global_iterator i = mod_->global_begin();
300 i != mod_->global_end(); i++) {
301
302 SmallString<256> Buffer;
303 mang_->getNameWithPrefix(Buffer, &(*i), false);
304 TCEString name(Buffer.c_str());
305
306 const llvm::GlobalObject& gv = *i;
307 MaybeAlign gvAlign = gv.getAlign();
308
309 if (gv.hasSection() &&
310 gv.getSection() == std::string("llvm.metadata")) {
311 // do not write debug constants to the data section
312 continue;
313 }
314
315 if (name == END_SYMBOL_NAME) {
316 // Skip original _end symbol.
317 continue;
318 }
319
320 if (name == "__dso_handle") {
321 // Should not be needed without dynamic library support.
322 continue;
323 }
324
325 if (!i->hasInitializer()) {
326 std::cerr << "Initializer missing for: " << name << std::endl;
327 assert(false && "No initializer. External linkage?");
328 }
329
330 const Constant* initializer = i->getInitializer();
331 TYPE_CONST Type* type = initializer->getType();
332
333 DataDef def;
334 def.name = name;
335 def.address = 0;
336 def.addressSpaceId =
337 cast<PointerType>(gv.getType())->getAddressSpace();
338 #ifdef LLVM_OLDER_THAN_16
339 def.alignment = std::max(gvAlign.hasValue()? gvAlign->value():0, (long unsigned int)(dl_->getPrefTypeAlignment(type)));
340 #else
341 def.alignment = std::max(gvAlign.has_value()? gvAlign->value():0, (long unsigned int)(dl_->getPrefTypeAlignment(type)));
342 #endif
343 def.size = dl_->getTypeStoreSize(type);
344 // memcpy seems to assume global values are aligned by 4
345 if (def.size > def.alignment) {
346 def.alignment = std::max(def.alignment, tm->stackAlignment());
347 }
348
349 assert(def.alignment != 0);
350
351 if (isInitialized(initializer)) {
352 def.initialize = true;
353 data_.push_back(def);
354 } else {
355 def.initialize = false;
356 udata_.push_back(def);
357 }
358 }
359
360 // Map initialized data to memory.
361 for (unsigned i = 0; i < data_.size(); i++) {
362
363 TTAMachine::AddressSpace& aSpace =
365
366 unsigned& dataEndPos = dataEnd(aSpace);
368
369 // padding
370 unsigned pad = 0;
371 while ((dataEndPos + pad) % data_[i].alignment != 0) pad++;
372 if (pad > 0) {
373 TTAProgram::Address address(dataEndPos, aSpace);
376 address, pad, mach_->isLittleEndian(), NULL, true));
377 dataEndPos += pad;
378 }
379
380 dataLabels_[data_[i].name] = dataEndPos;
381 data_[i].address = dataEndPos;
382
383 // Add data label.
384 TTAProgram::Address addr(dataEndPos, aSpace);
385 TTAProgram::DataLabel* label =
386 new TTAProgram::DataLabel(data_[i].name, addr, gscope);
387
388 gscope.addDataLabel(label);
389
390 dataEndPos += data_[i].size;
391 }
392
393 // Map uninitialized data to memory.
394 for (unsigned i = 0; i < udata_.size(); i++) {
395
396 TTAMachine::AddressSpace& aSpace =
398
399 unsigned& dataEndPos = dataEnd(aSpace);
401
402 // padding
403 unsigned pad = 0;
404 while ((dataEndPos + pad) % udata_[i].alignment != 0) pad++;
405 if (pad > 0) {
406 TTAProgram::Address address(dataEndPos, aSpace);
409 address, pad, mach_->isLittleEndian()));
410
411 dataEndPos += pad;
412 }
413
414 udata_[i].address = dataEndPos;
415 dataLabels_[udata_[i].name] = dataEndPos;
416
417 // Add data label.
418 TTAProgram::Address addr(dataEndPos, aSpace);
419 TTAProgram::DataLabel* label =
420 new TTAProgram::DataLabel(udata_[i].name, addr, gscope);
421
422 gscope.addDataLabel(label);
423 dataEndPos += udata_[i].size;
424 }
425}
virtual int operationCount() const
const std::string & name() const
bool isInitialized(const Constant *cv)
TTAMachine::AddressSpace * instrAddressSpace_

References TTAProgram::DataMemory::addDataDefinition(), TTAProgram::Scope::addDataLabel(), llvm::LLVMTCEBuilder::DataDef::address, TTAMachine::FunctionUnit::addressSpace(), addressSpaceById(), llvm::LLVMTCEBuilder::DataDef::addressSpaceId, addressSpaceId(), TTAMachine::Machine::addressSpaceNavigator(), llvm::LLVMTCEBuilder::DataDef::alignment, assert, TTAMachine::Machine::controlUnit(), TTAMachine::Machine::Navigator< ComponentType >::count(), data_, dataEnd(), dataInitialized_, dataLabels_, dataMemoryForAddressSpace(), defaultDataAddressSpace_, dl_, END_SYMBOL_NAME, TTAMachine::Machine::functionUnitNavigator(), TTAProgram::Program::globalScope(), llvm::LLVMTCEBuilder::DataDef::initialize, instrAddressSpace_, isInitialized(), TTAMachine::Machine::isLittleEndian(), TTAMachine::Machine::Navigator< ComponentType >::item(), Application::logStream(), mach_, mang_, mod_, multiDataMemMachine_, llvm::LLVMTCEBuilder::DataDef::name, TTAMachine::HWOperation::name(), TTAMachine::Component::name(), TTAMachine::FunctionUnit::operation(), TTAMachine::FunctionUnit::operationCount(), opset_, prog_, llvm::LLVMTCEBuilder::DataDef::size, llvm::TCETargetMachine::stackAlignment(), StringTools::stringToLower(), tm_, TYPE_CONST, udata_, and Application::verboseLevel().

Referenced by writeMachineFunction(), and llvm::LLVMTCEIRBuilder::writeMachineFunction().

Here is the call graph for this function:

◆ initMembers()

void LLVMTCEBuilder::initMembers ( )
private

Definition at line 172 of file LLVMTCEBuilder.cc.

172 {
173 mod_ = NULL;
174 tm_ = NULL;
175 prog_ = NULL;
176 mach_ = NULL;
177 mang_ = NULL;
178 noAliasFound_ = false;
179 multiAddrSpacesFound_ = false;
180 multiDataMemMachine_ = false;
181 spillMoveCount_ = 0;
182 dataInitialized_ = false;
184
185 if (Application::cmdLineOptions() != NULL) {
186 options_ =
187 dynamic_cast<LLVMTCECmdLineOptions*>(
189 }
190}
static CmdLineOptions * cmdLineOptions()

References Application::cmdLineOptions(), dataInitialized_, initialStackPointerValue_, mach_, mang_, mod_, multiAddrSpacesFound_, multiDataMemMachine_, noAliasFound_, options_, prog_, spillMoveCount_, and tm_.

Referenced by LLVMTCEBuilder(), and LLVMTCEBuilder().

Here is the call graph for this function:

◆ isBaseOffsetMemOperation()

bool llvm::LLVMTCEBuilder::isBaseOffsetMemOperation ( const Operation operation) const
private

◆ isInitialized()

bool LLVMTCEBuilder::isInitialized ( const Constant *  cv)
private

Returns true if the Constant value structure has initialized data.

Parameters
cvInitializer to check.
Returns
True, if the initializer has any non-Null data.

Definition at line 2652 of file LLVMTCEBuilder.cc.

2652 {
2653
2654 if ((dyn_cast<ConstantArray>(cv) != NULL) ||
2655 (dyn_cast<ConstantStruct>(cv) != NULL) ||
2656 (dyn_cast<ConstantVector>(cv) != NULL)) {
2657
2658 for (unsigned i = 0, e = cv->getNumOperands(); i != e; ++i) {
2659 if (isInitialized(cast<Constant>(cv->getOperand(i)))) {
2660 return true;
2661 }
2662 }
2663 return false;
2664 }
2665
2666 return true;
2667}

References isInitialized().

Referenced by initDataSections(), and isInitialized().

Here is the call graph for this function:

◆ isInlineAsm()

bool LLVMTCEBuilder::isInlineAsm ( const MachineInstr &  instr)
staticprotected

Returns true if the instruction is real inline asm aka. holds moves.

Returns false if instruction is not inline asm. This also return false for operation macros (_TCE_OP(...)) that also use inline asm statements in C code.

Parameters
instrThe instruction.

Definition at line 3912 of file LLVMTCEBuilder.cc.

3912 {
3913 return InlineAsmParser::isInlineAsm(instr);
3914}
static bool isInlineAsm(const llvm::MachineInstr &mi)

References InlineAsmParser::isInlineAsm().

Referenced by llvm::LLVMTCEIRBuilder::buildTCECFG(), and emitInlineAsm().

Here is the call graph for this function:

◆ isProgramUsingRestrictedPointers()

bool llvm::LLVMTCEBuilder::isProgramUsingRestrictedPointers ( ) const
inline

Definition at line 123 of file LLVMTCEBuilder.hh.

123{ return noAliasFound_; }

References noAliasFound_.

Referenced by LLVMBackend::compile().

◆ isTTATarget()

virtual bool llvm::LLVMTCEBuilder::isTTATarget ( ) const
inlinevirtual

Definition at line 132 of file LLVMTCEBuilder.hh.

132 {
133 return (dynamic_cast<const TCETargetMachine*>(
134 &targetMachine()) != NULL);
135 }

References targetMachine().

Referenced by llvm::LLVMTCEIRBuilder::buildTCECFG(), createTerminal(), llvm::LLVMTCEIRBuilder::raPortDRegNum(), llvm::LLVMTCEIRBuilder::registerFileName(), and llvm::LLVMTCEIRBuilder::registerIndex().

Here is the call graph for this function:

◆ mbbName()

std::string LLVMTCEBuilder::mbbName ( const MachineBasicBlock &  mbb)
protected

Returns string identifier for a basic block.

These identifiers are used for the BB -> POM instruction book keeping.

Parameters
mbbBasic block object.
Returns
String identifier for the basic block.

Definition at line 2636 of file LLVMTCEBuilder.cc.

2636 {
2637 SmallString<256> Buffer;
2638 mang_->getNameWithPrefix(Buffer, &mbb.getParent()->getFunction(), false);
2639 TCEString name(Buffer.c_str());
2640 name += " ";
2641 name += Conversion::toString(mbb.getNumber());
2642 return name;
2643}
static std::string toString(const T &source)

References mang_, and Conversion::toString().

Referenced by llvm::LLVMTCEIRBuilder::buildTCECFG(), createMBBReference(), and writeMachineFunction().

Here is the call graph for this function:

◆ operationName()

virtual TCEString llvm::LLVMTCEBuilder::operationName ( const MachineInstr &  mi) const
protectedpure virtual

◆ padToAlignment()

void LLVMTCEBuilder::padToAlignment ( int  addressSpaceId,
unsigned &  addr,
unsigned  align 
)
private

Pads data memory with zeroes until desired alignment is reached.

Zero padding is only added when necessary. That is the address is already aligned.

Parameters
addressSpaceIdThe address space id.
addrThe current address, which is updated to the desired alignment after the call.
alignThe desired alignment.

Definition at line 921 of file LLVMTCEBuilder.cc.

922 {
923
926
927 unsigned pad = 0;
928 while ((addr + pad) % align != 0) pad++;
929
930 // Pad with zeros to correct alignment.
931 if (pad > 0) {
932 std::vector<MinimumAddressableUnit> zeros(pad, 0);
933 TTAProgram::Address address(addr, aSpace);
936 address, zeros, mach_->isLittleEndian()));
937
938 addr += pad;
939 }
940}

References TTAProgram::DataMemory::addDataDefinition(), addressSpaceById(), addressSpaceId(), dataMemoryForAddressSpace(), TTAMachine::Machine::isLittleEndian(), and mach_.

Referenced by createDataDefinition(), and emitConstantPool().

Here is the call graph for this function:

◆ raPortDRegNum()

virtual unsigned llvm::LLVMTCEBuilder::raPortDRegNum ( ) const
protectedpure virtual

◆ registerFileName()

virtual TCEString llvm::LLVMTCEBuilder::registerFileName ( unsigned  llvmRegNum) const
protectedpure virtual

◆ registerIndex()

virtual int llvm::LLVMTCEBuilder::registerIndex ( unsigned  llvmRegNum) const
protectedpure virtual

◆ registerName()

TCEString llvm::LLVMTCEBuilder::registerName ( unsigned  llvmRegNum) const
protected

◆ result()

TTAProgram::Program * LLVMTCEBuilder::result ( )

Returns the program built during the pass.

Returns
Result program object built.
Exceptions
NotAvailableIf program is not ready.

Definition at line 3717 of file LLVMTCEBuilder.cc.

3717 {
3718 return prog_;
3719}

References prog_.

Referenced by LLVMBackend::compile(), and llvm::LLVMTCEPOMBuilder::emitMove().

◆ runOnMachineFunction()

bool LLVMTCEBuilder::runOnMachineFunction ( MachineFunction &  mf)
protected

Creates POM procedure of a MachineFunction object and adds it to the current program.

Parameters
mfMachineFunction to process.
Returns
Always false.

Definition at line 951 of file LLVMTCEBuilder.cc.

951 {
952 return writeMachineFunction(mf);
953}
virtual bool writeMachineFunction(MachineFunction &MF)

References writeMachineFunction().

Here is the call graph for this function:

◆ setInitialStackPointerValue()

void LLVMTCEBuilder::setInitialStackPointerValue ( unsigned  value)

Sets the value the stack pointer should be initialized to.

Definition at line 1244 of file LLVMTCEBuilder.cc.

1244 {
1246}

References initialStackPointerValue_.

Referenced by LLVMBackend::compile().

◆ spDRegNum()

virtual unsigned llvm::LLVMTCEBuilder::spDRegNum ( ) const
protectedpure virtual

◆ targetMachine()

const TargetMachine & llvm::LLVMTCEBuilder::targetMachine ( ) const
inlineprotected

◆ writeMachineFunction()

bool LLVMTCEBuilder::writeMachineFunction ( MachineFunction &  mf)
protectedvirtual

Writes machine function to POM.

Actually does things to MachineFunction which was supposed to be done in runOnMachineFunction, but which cannot be done during that, because MachineDCE is not ready yet at that time...

Reimplemented in llvm::LLVMTCEIRBuilder.

Definition at line 963 of file LLVMTCEBuilder.cc.

963 {
964
965 // the new TTA backend does not initialize TCETargetMachine
966 // in construction (at least not yet)
967 if (tm_ == NULL)
968 tm_ = dynamic_cast<const TCETargetMachine*>(&mf.getTarget());
969
970 assert(tm_ != NULL);
971
972 curFrameInfo_ = &mf.getFrameInfo();
973 assert(curFrameInfo_ != NULL);
974
975 // ensure data sections have been initialized
977
978 // omit empty functions..
979 if (mf.begin() == mf.end()) return true;
980
981 // TODO: make list of mf's which for the pass will be ran afterwards..
982
983 SmallString<256> Buffer;
984 mang_->getNameWithPrefix(Buffer, &mf.getFunction(), false);
985 TCEString fnName(Buffer.c_str());
986
987 emitConstantPool(*mf.getConstantPool());
988
991
992 prog_->addProcedure(proc);
993
994 std::set<std::string> emptyMBBs;
995
996 bool firstInsOfProc = true;
997 spillMoveCount_ = 0;
998 // iterate basic blocks from MachineFunction
999 for (MachineFunction::const_iterator i = mf.begin();
1000 i != mf.end(); i++) {
1001
1002 bool newMBB = true;
1003
1004 // iterate MachineInstr from basic blocks
1005 for (MachineBasicBlock::const_iterator j = i->begin();
1006 j != i->end(); j++) {
1007
1008 TTAProgram::Instruction* instr = NULL;
1009#ifdef DEBUG_LLVMTCEBUILDER
1010 std::cerr << "### converting: ";
1011 std::cerr << std::endl;
1012#endif
1013 instr = emitInstruction(&*j, proc);
1014
1015 // Pseudo instructions:
1016 if (instr == NULL) continue;
1017
1020 << "ERROR: The machine contains multiple data address spaces "
1021 << "and ambigious memory accessing moves '"
1022 << instr->toString() << "' were found." << std::endl;
1023 abort();
1024 }
1025
1026 // If there was any empty basic blocks before this instruction,
1027 // set the basic blocks to point the next available (this)
1028 // instruction.
1029 while (!emptyMBBs.empty()) {
1030 mbbs_[*emptyMBBs.begin()] = instr;
1031 emptyMBBs.erase(emptyMBBs.begin());
1032 }
1033
1034 std::string mbb = mbbName(*i);
1035
1036 // Keep book of first instructions in basic blocks.
1037 if (newMBB) {
1038 newMBB = false;
1040 mbbs_[mbb] = instr;
1041 bbIndex_[(*i).getBasicBlock()] = instr;
1042 }
1043
1044 // Keep book of first instructions in functions.
1045 if (firstInsOfProc) {
1047 instructionReferenceManager().createReference(*instr);
1049 new TTAProgram::CodeLabel(ref, fnName));
1050
1051 codeLabels_[fnName] = instr;
1052 firstInsOfProc = false;
1053 }
1054 }
1055
1056 // If the basic block didn't hold any instructions
1057 // (i.e. it probably contained only pseudo instructions),
1058 // add it to the set of empty BBs that will be set to point
1059 // the next instruction in the program.
1060 if (newMBB) {
1061 emptyMBBs.insert(mbbName(*i));
1062 }
1063 }
1064
1065 // if the procedure would otherwise be empty, add a dummy instruction there,
1066 // and make the procedure cdelabel to point it.
1067 if (firstInsOfProc) {
1069 proc->add(dummyIns);
1070
1072 instructionReferenceManager().createReference(*dummyIns);
1074 new TTAProgram::CodeLabel(ref, fnName));
1075
1076 codeLabels_[fnName] = dummyIns;
1077 }
1078 if (Application::verboseLevel() > 0) {
1080 << "spill moves in " <<
1081 (std::string)(mf.getFunction().getName()) << ": "
1082 << spillMoveCount_ << std::endl;
1083 }
1084 return false;
1085}
std::string toString() const
void add(Instruction *ins)
Definition Procedure.cc:160
void addProcedure(Procedure *proc)
Definition Program.cc:524
virtual void addCodeLabel(const CodeLabel *codeLabel)
Definition Scope.cc:376
bool hasAmbiguousASpaceRefs(const TTAProgram::Instruction &instr) const
void emitConstantPool(const llvm::MachineConstantPool &cp)
TTAProgram::Instruction * emitInstruction(const MachineInstr *mi, TTAProgram::CodeSnippet *proc)

References TTAProgram::Procedure::add(), TTAProgram::Scope::addCodeLabel(), TTAProgram::Program::addProcedure(), assert, bbIndex_, codeLabels_, MapTools::containsKey(), curFrameInfo_, emitConstantPool(), emitInstruction(), TTAProgram::Program::globalScope(), hasAmbiguousASpaceRefs(), initDataSections(), instrAddressSpace_, Application::logStream(), mang_, mbbName(), mbbs_, multiDataMemMachine_, prog_, spillMoveCount_, tm_, TTAProgram::Instruction::toString(), and Application::verboseLevel().

Referenced by runOnMachineFunction().

Here is the call graph for this function:

Member Data Documentation

◆ bbIndex_

std::map<const llvm::BasicBlock*, TTAProgram::Instruction*> llvm::LLVMTCEBuilder::bbIndex_
private

Basic Block -> first instruction in the BB map.

Definition at line 451 of file LLVMTCEBuilder.hh.

Referenced by firstInstructionOfBasicBlock(), and writeMachineFunction().

◆ codeLabelReferences_

std::map<TTAProgram::TerminalInstructionAddress*, std::string> llvm::LLVMTCEBuilder::codeLabelReferences_
private

Dummy code label references that have to be fixed after all instrutions have been built.

Definition at line 459 of file LLVMTCEBuilder.hh.

Referenced by createSymbolReference(), and doFinalization().

◆ codeLabels_

std::map<std::string, TTAProgram::Instruction*> llvm::LLVMTCEBuilder::codeLabels_
protected

◆ cpData_

std::vector<ConstantDataDef> llvm::LLVMTCEBuilder::cpData_
private

Definition at line 445 of file LLVMTCEBuilder.hh.

Referenced by doFinalization(), and emitConstantPool().

◆ curFrameInfo_

MachineFrameInfo* llvm::LLVMTCEBuilder::curFrameInfo_
protected

◆ currentFnCP_

std::map<unsigned, unsigned> llvm::LLVMTCEBuilder::currentFnCP_
private

Constant pool for the current machine function. Map key is constant pool index and the value is address.

Definition at line 476 of file LLVMTCEBuilder.hh.

Referenced by createTerminal(), and emitConstantPool().

◆ data_

std::vector<DataDef> llvm::LLVMTCEBuilder::data_
private

Data definitions.

Definition at line 443 of file LLVMTCEBuilder.hh.

Referenced by doFinalization(), and initDataSections().

◆ dataEnds_

std::map<TTAMachine::AddressSpace*, unsigned> llvm::LLVMTCEBuilder::dataEnds_
private

The first position after the last data in the given address space.

Definition at line 479 of file LLVMTCEBuilder.hh.

Referenced by dataEnd().

◆ dataInitialized_

bool llvm::LLVMTCEBuilder::dataInitialized_
private

Definition at line 495 of file LLVMTCEBuilder.hh.

Referenced by doInitialization(), initDataSections(), and initMembers().

◆ dataLabels_

std::map<std::string, unsigned> llvm::LLVMTCEBuilder::dataLabels_
private

◆ defaultDataAddressSpace_

TTAMachine::AddressSpace* llvm::LLVMTCEBuilder::defaultDataAddressSpace_
private

The default data memory address space (address space 0).

Definition at line 430 of file LLVMTCEBuilder.hh.

Referenced by addressSpaceById(), and initDataSections().

◆ dl_

const llvm::DataLayout* llvm::LLVMTCEBuilder::dl_
private

◆ dmemIndex_

DataMemIndex llvm::LLVMTCEBuilder::dmemIndex_
private

Definition at line 440 of file LLVMTCEBuilder.hh.

Referenced by dataMemoryForAddressSpace(), and doFinalization().

◆ endReferences_

std::vector<std::shared_ptr<TTAProgram::Move> > llvm::LLVMTCEBuilder::endReferences_
private

Dummy references to the _end symbol.

Definition at line 468 of file LLVMTCEBuilder.hh.

Referenced by createMove(), and doFinalization().

◆ functionAtATime_

bool llvm::LLVMTCEBuilder::functionAtATime_
protected

◆ functions_

std::vector<MachineFunction*> llvm::LLVMTCEBuilder::functions_
private

List of machine functions collected from runForMachineFunction.

Definition at line 493 of file LLVMTCEBuilder.hh.

◆ globalCP_

std::map<const llvm::Constant*, unsigned> llvm::LLVMTCEBuilder::globalCP_
private

Global constant pool for all constants gathered from machine functions. Map key is unique constant and the value is address of the constant.

Definition at line 473 of file LLVMTCEBuilder.hh.

Referenced by emitConstantPool().

◆ ID

char LLVMTCEBuilder::ID = 0
static

Definition at line 105 of file LLVMTCEBuilder.hh.

◆ initialStackPointerValue_

unsigned llvm::LLVMTCEBuilder::initialStackPointerValue_
protected

◆ instrAddressSpace_

TTAMachine::AddressSpace* llvm::LLVMTCEBuilder::instrAddressSpace_
private

Definition at line 427 of file LLVMTCEBuilder.hh.

Referenced by initDataSections(), and writeMachineFunction().

◆ labeledPOs_

std::map<TCEString, ProgramOperationPtr > llvm::LLVMTCEBuilder::labeledPOs_
private

◆ mach_

TTAMachine::Machine* llvm::LLVMTCEBuilder::mach_
protected

◆ mang_

llvm::Mangler* llvm::LLVMTCEBuilder::mang_
protected

◆ MAU_BITS

unsigned LLVMTCEBuilder::MAU_BITS = 8
staticprivate

Target architechture MAU size in bits.

Definition at line 419 of file LLVMTCEBuilder.hh.

Referenced by createIntDataDefinition().

◆ mbbReferences_

std::map<TTAProgram::TerminalInstructionAddress*, std::string> llvm::LLVMTCEBuilder::mbbReferences_
private

Dummy basic block references that have to be fixed after all basic blocks have been built.

Definition at line 465 of file LLVMTCEBuilder.hh.

Referenced by createMBBReference(), and doFinalization().

◆ mbbs_

std::map<std::string, TTAProgram::Instruction*> llvm::LLVMTCEBuilder::mbbs_
private

Machine basic block -> first instruction in the BB map.

Definition at line 448 of file LLVMTCEBuilder.hh.

Referenced by doFinalization(), and writeMachineFunction().

◆ mod_

llvm::Module* llvm::LLVMTCEBuilder::mod_
private

◆ multiAddrSpacesFound_

bool llvm::LLVMTCEBuilder::multiAddrSpacesFound_
private

set to true in case at least one non-default address space memory access has been found in the generated code

Definition at line 490 of file LLVMTCEBuilder.hh.

Referenced by addPointerAnnotations(), and initMembers().

◆ multiDataMemMachine_

bool llvm::LLVMTCEBuilder::multiDataMemMachine_
private

Set to true in case this machine has more than one data address spaces.

Definition at line 434 of file LLVMTCEBuilder.hh.

Referenced by addPointerAnnotations(), addressSpaceById(), initDataSections(), initMembers(), and writeMachineFunction().

◆ noAliasFound_

bool llvm::LLVMTCEBuilder::noAliasFound_
private

set to true in case at least one 'noalias' attribute (from the use of 'restricted' pointers) has been found

Definition at line 487 of file LLVMTCEBuilder.hh.

Referenced by addPointerAnnotations(), initMembers(), and isProgramUsingRestrictedPointers().

◆ opset_

std::set<std::string> llvm::LLVMTCEBuilder::opset_
protected

The operations supported by the current target machine.

Definition at line 253 of file LLVMTCEBuilder.hh.

Referenced by getHWOperation(), initDataSections(), and llvm::LLVMTCEIRBuilder::LLVMTCEIRBuilder().

◆ options_

LLVMTCECmdLineOptions* llvm::LLVMTCEBuilder::options_ = nullptr
protected

◆ POINTER_SIZE_32

unsigned LLVMTCEBuilder::POINTER_SIZE_32 = 4
staticprivate

Target architecture pointer size in maus.

Definition at line 422 of file LLVMTCEBuilder.hh.

Referenced by createIntDataDefinition().

◆ POINTER_SIZE_64

unsigned LLVMTCEBuilder::POINTER_SIZE_64 = 8
staticprivate

Definition at line 423 of file LLVMTCEBuilder.hh.

Referenced by createIntDataDefinition().

◆ pregions_

PRegionMarkerAnalyzer* llvm::LLVMTCEBuilder::pregions_
protected

◆ prog_

TTAProgram::Program* llvm::LLVMTCEBuilder::prog_
protected

◆ spillMoveCount_

int llvm::LLVMTCEBuilder::spillMoveCount_
protected

◆ symbolicPORefs_

std::set<TTAProgram::TerminalProgramOperation*> llvm::LLVMTCEBuilder::symbolicPORefs_
private

◆ tm_

const llvm::TargetMachine* llvm::LLVMTCEBuilder::tm_
protected

◆ udata_

std::vector<DataDef> llvm::LLVMTCEBuilder::udata_
private

Definition at line 444 of file LLVMTCEBuilder.hh.

Referenced by doFinalization(), and initDataSections().


The documentation for this class was generated from the following files: