OpenASIP 2.2
Loading...
Searching...
No Matches
Public Types | Static Public Member Functions | Private Member Functions | Static Private Member Functions | Static Private Attributes | List of all members
MachineInfo Class Reference

#include <MachineInfo.hh>

Collaboration diagram for MachineInfo:
Collaboration graph

Public Types

typedef TCETools::CIStringSet OperationSet
 
typedef std::vector< const TTAMachine::FUPort * > ConstPortList
 

Static Public Member Functions

static int maxLatency (const TTAMachine::Machine &mach, TCEString &opName)
 
static OperationSet getOpset (const TTAMachine::Machine &mach)
 
static OperationSet getOpset (const TTAMachine::ControlUnit &gcu)
 
static ConstPortList getPortBindingsOfOperation (const TTAMachine::Machine &mach, const std::string &operation)
 
static const TTAMachine::FUPortgetBoundPort (const TTAMachine::FunctionUnit &fu, const std::string &opName, int operandIndex)
 
static bool supportsOperation (const TTAMachine::Machine &mach, TCEString operation)
 
static TTAMachine::AddressSpacedefaultDataAddressSpace (const TTAMachine::Machine &mach)
 
static int longestGuardLatency (const TTAMachine::Machine &mach)
 
static OperandoperandFromPort (const TTAMachine::HWOperation &hwOp, const TTAMachine::FUPort &port)
 
static int maxMemoryAlignment (const TTAMachine::Machine &mach)
 
static bool templatesUsesSlot (const TTAMachine::Machine &mach, const std::string &slotName)
 
static std::set< TTAMachine::InstructionTemplate * > templatesUsingSlot (const TTAMachine::Machine &mach, const std::string &slotName)
 
static bool canEncodeImmediateInteger (const TTAMachine::Machine &mach, int64_t imm, unsigned destWidth=UINT_MAX)
 
static bool canEncodeImmediateInteger (const TTAMachine::InstructionTemplate &temp, int64_t imm, unsigned destWidth=UINT_MAX)
 
static int triggerIndex (const TTAMachine::Machine &machine, const Operation &op)
 
static int triggerIndex (const TTAMachine::FunctionUnit &fu, const Operation &op)
 
static bool canEncodeImmediateInteger (const TTAMachine::Bus &bus, int64_t imm, unsigned destWidth=UINT_MAX)
 
static unsigned findWidestOperand (const TTAMachine::Machine &machine, bool vector)
 
static unsigned numberOfRegisters (const TTAMachine::Machine &machine, unsigned width)
 
static bool supportsBoolRegisterGuardedJumps (const TTAMachine::Machine &machine)
 
static bool supportsPortGuardedJumps (const TTAMachine::Machine &machine)
 
static bool supportsPortGuardedJump (const TTAMachine::Machine &machine, bool inverted, const TCEString &opName)
 
static std::vector< const TTAMachine::FunctionUnit * > findLockUnits (const TTAMachine::Machine &machine)
 
static OperationosalOperation (const TTAMachine::HWOperation &hwOp)
 

Private Member Functions

 MachineInfo ()
 

Static Private Member Functions

template<typename PortType >
static PortType & portFromOperand (const TTAMachine::HWOperation &hwOp, const TTAMachine::FUPort &port)
 

Static Private Attributes

static const TCEString LOCK_READ_ = "lock_read"
 
static const TCEString TRY_LOCK_ADDR_ = "try_lock_addr"
 
static const TCEString UNLOCK_ADDR_ = "unlock_addr"
 

Detailed Description

Definition at line 58 of file MachineInfo.hh.

Member Typedef Documentation

◆ ConstPortList

typedef std::vector<const TTAMachine::FUPort*> MachineInfo::ConstPortList

Definition at line 61 of file MachineInfo.hh.

◆ OperationSet

Definition at line 60 of file MachineInfo.hh.

Constructor & Destructor Documentation

◆ MachineInfo()

MachineInfo::MachineInfo ( )
private

Member Function Documentation

◆ canEncodeImmediateInteger() [1/3]

bool MachineInfo::canEncodeImmediateInteger ( const TTAMachine::Bus bus,
int64_t  imm,
unsigned  destWidth = UINT_MAX 
)
static

Definition at line 390 of file MachineInfo.cc.

391 {
392
393 size_t requiredBitsSigned =
394 std::min((unsigned)MathTools::requiredBitsSigned((long int)imm), destWidth);
395 size_t requiredBitsUnsigned =
396 std::min((unsigned)MathTools::requiredBits(imm), destWidth);
397
398 size_t requiredBits = bus.signExtends() ?
399 requiredBitsSigned : requiredBitsUnsigned;
400 // In case the short immediate can write all bits in
401 // the bus, let's assume this is the word width to the
402 // target operation and the extension mode can be
403 // assumed to be 'signed' (the targeted operation can
404 // interpret the value in the bus either way), we
405 // just have to be sure there is no information loss
406 // in the upper bits. This breaks with
407 // multibitwidth scalar machines, e.g., ones with
408 // INT32 datapath combined with FLOAT64 because now
409 // it assumes the constant can be written in case
410 // there's a 32b immediate slot for the INT32 bus. (*)
411 if (bus.width() == bus.immediateWidth() &&
412 requiredBitsSigned < requiredBits)
413 requiredBits = requiredBitsSigned;
414 if (static_cast<size_t>(bus.immediateWidth()) >= requiredBits)
415 return true;
416 return false;
417}
static int requiredBits(unsigned long int number)
static int requiredBitsSigned(SLongWord number)
int width() const
Definition Bus.cc:149
int immediateWidth() const
Definition Bus.cc:160
bool signExtends() const
Definition Bus.cc:171

References TTAMachine::Bus::immediateWidth(), MathTools::requiredBits(), MathTools::requiredBitsSigned(), TTAMachine::Bus::signExtends(), and TTAMachine::Bus::width().

Here is the call graph for this function:

◆ canEncodeImmediateInteger() [2/3]

bool MachineInfo::canEncodeImmediateInteger ( const TTAMachine::InstructionTemplate temp,
int64_t  imm,
unsigned  destWidth = UINT_MAX 
)
static

Definition at line 465 of file MachineInfo.cc.

467 {
468 size_t requiredBitsSigned =
469 std::min((unsigned)MathTools::requiredBitsSigned(
470 static_cast<SLongWord>(imm)), destWidth);
471 size_t requiredBitsUnsigned =
472 std::min((unsigned)MathTools::requiredBits(
473 static_cast<ULongWord>(imm)), destWidth);
474
475 const TTAMachine::Machine& mach = *temp.machine();
478 for (const TTAMachine::ImmediateUnit* iu: mach.immediateUnitNavigator()) {
479 size_t requiredBits = iu->signExtends() ?
480 requiredBitsSigned : requiredBitsUnsigned;
481 size_t supportedW = temp.supportedWidth(*iu);
482 // see above (*). Same applies here: if the template encodes
483 // as many bits as the buses that the IU can write to are wide,
484 // the extension mode is meaningless -> can interpret it as one wishes
485 // here.
486 size_t maxBusW = 0;
487 std::set<const TTAMachine::Bus*> buses;
489 *iu, buses);
490 for (auto bus: buses) {
491 if (static_cast<size_t>(bus->width()) > maxBusW)
492 maxBusW = bus->width();
493 }
494
495 if (supportedW == maxBusW &&
496 requiredBitsSigned < requiredBits)
497 requiredBits = requiredBitsSigned;
498 if (supportedW >= requiredBits)
499 return true;
500
501 }
502
503 return false;
504}
unsigned long ULongWord
Definition BaseType.hh:51
long SLongWord
Definition BaseType.hh:52
static void appendConnectedDestinationBuses(const TTAMachine::Port &port, std::set< const TTAMachine::Bus * > &buses)
virtual Machine * machine() const
virtual ImmediateUnitNavigator immediateUnitNavigator() const
Definition Machine.cc:416

References MachineConnectivityCheck::appendConnectedDestinationBuses(), TTAMachine::Machine::immediateUnitNavigator(), TTAMachine::Component::machine(), MathTools::requiredBits(), MathTools::requiredBitsSigned(), and TTAMachine::InstructionTemplate::supportedWidth().

Here is the call graph for this function:

◆ canEncodeImmediateInteger() [3/3]

bool MachineInfo::canEncodeImmediateInteger ( const TTAMachine::Machine mach,
int64_t  imm,
unsigned  destWidth = UINT_MAX 
)
static

Checks if the given immediate can be transferred at all in the given machine.

Takes in account the move slots' or the immediate unit's extension mode when considering the encoding of the given constant's bits. In case this function returns true, the register copy adder or similar pass should be able to route the constant to the wanted destination(s), in case no direct bus with the immediate support is found. In case the destination (port) is known, its width should be set to destWidth to constraint the required immediate extension width (in case the move tries to write to a port narrower than the immediate actually requires bits, the bug is earlier in the compilation).

A complex example: a move where a negative constant with minimal encoding of 7b is transported through a 32b bus to a 8b destination with a 8b move slot that uses zero extension mode. The zero extension mode does not fill up the upper bits with 1, but it does not lead to information loss as the destination uses only the lower 8 bits which can be encoded directly to the immediate field, thus the extension is not needed.

Definition at line 444 of file MachineInfo.cc.

445 {
446
447 const Machine::BusNavigator& busNav = mach.busNavigator();
448
449 // first check the short immediate slots
450 for (int bi = 0; bi < busNav.count(); ++bi) {
451 const Bus& bus = *busNav.item(bi);
452 if (canEncodeImmediateInteger(bus, imm, destWidth))
453 return true;
454 }
455
456 // then the long immediate templates
457 for (const TTAMachine::InstructionTemplate* temp: mach.instructionTemplateNavigator())
458 if (canEncodeImmediateInteger(*temp, imm, destWidth))
459 return true;
460
461 return false;
462}
static bool canEncodeImmediateInteger(const TTAMachine::Machine &mach, int64_t imm, unsigned destWidth=UINT_MAX)
ComponentType * item(int index) const
virtual BusNavigator busNavigator() const
Definition Machine.cc:356

References TTAMachine::Machine::busNavigator(), canEncodeImmediateInteger(), TTAMachine::Machine::Navigator< ComponentType >::count(), TTAMachine::Machine::instructionTemplateNavigator(), and TTAMachine::Machine::Navigator< ComponentType >::item().

Referenced by canEncodeImmediateInteger(), llvm::LLVMTCEBuilder::emitSPInitialization(), and ConstantTransformer::runOnMachineFunction().

Here is the call graph for this function:

◆ defaultDataAddressSpace()

TTAMachine::AddressSpace * MachineInfo::defaultDataAddressSpace ( const TTAMachine::Machine mach)
static

Finds the default data address space for given machine.

Parameters
machThe machine whose default data address space is requested.
Returns
Default data address space for given machine

Definition at line 176 of file MachineInfo.cc.

176 {
177
178 const AddressSpace& instrAS = *mach.controlUnit()->addressSpace();
179
182 int asCount = asNav.count();
183 for (int i = 0; i < asCount; i++) {
184 // if there are more than two address spaces, choose one which
185 // contains numerical id 0
186 // otherwise choose the one which is not the instruction address space
187 if (asCount > 2) {
188 if (asNav.item(i)->hasNumericalId(0)) return asNav.item(i);
189 } else {
190 if (asNav.item(i) != &instrAS) return asNav.item(i);
191 }
192 }
193
194 // no data address space found
195 throw IllegalMachine(
196 __FILE__, __LINE__, __func__,
197 "Target machine has no data address space");
198 return NULL;
199}
#define __func__
virtual AddressSpace * addressSpace() const
virtual AddressSpaceNavigator addressSpaceNavigator() const
Definition Machine.cc:392
virtual ControlUnit * controlUnit() const
Definition Machine.cc:345

References __func__, TTAMachine::FunctionUnit::addressSpace(), TTAMachine::Machine::addressSpaceNavigator(), TTAMachine::Machine::controlUnit(), TTAMachine::Machine::Navigator< ComponentType >::count(), and TTAMachine::Machine::Navigator< ComponentType >::item().

Referenced by ITemplateBroker::findITemplates(), and MachineConnectivityCheck::requiredImmediateWidth().

Here is the call graph for this function:

◆ findLockUnits()

std::vector< const TTAMachine::FunctionUnit * > MachineInfo::findLockUnits ( const TTAMachine::Machine machine)
static

Searches for lock unit FUs and returns them.

Lock unit FU must have the correct operations and an address space

Parameters
machineArchitecture to be searched
Returns
Vector of found lock unit FUs

Definition at line 759 of file MachineInfo.cc.

759 {
760 std::vector<TCEString> requiredOperations;
761 requiredOperations.push_back(LOCK_READ_);
762 requiredOperations.push_back(TRY_LOCK_ADDR_);
763 requiredOperations.push_back(UNLOCK_ADDR_);
764
765 std::vector<const FunctionUnit*> lockUnits;
767 for (int i = 0; i < fuNav.count(); i++) {
768 const FunctionUnit* fu = fuNav.item(i);
769 bool hasCorrectOperations = true;
770 for (unsigned int i = 0; i < requiredOperations.size(); i++) {
771 if (!fu->hasOperation(requiredOperations.at(i))) {
772 hasCorrectOperations = false;
773 break;
774 }
775 }
776 if (hasCorrectOperations) {
777 if (!fu->hasAddressSpace()) {
778 TCEString msg;
779 msg << "Lock Unit " << fu->name() << " has no address space";
780 throw InvalidData(__FILE__, __LINE__, __func__, msg);
781 }
782 lockUnits.push_back(fu);
783 }
784 }
785 return lockUnits;
786}
TTAMachine::Machine * machine
the architecture definition of the estimated processor
static const TCEString LOCK_READ_
static const TCEString UNLOCK_ADDR_
static const TCEString TRY_LOCK_ADDR_
virtual TCEString name() const
virtual bool hasOperation(const std::string &name) const
virtual bool hasAddressSpace() const
virtual FunctionUnitNavigator functionUnitNavigator() const
Definition Machine.cc:380

References __func__, TTAMachine::Machine::Navigator< ComponentType >::count(), TTAMachine::Machine::functionUnitNavigator(), TTAMachine::FunctionUnit::hasAddressSpace(), TTAMachine::FunctionUnit::hasOperation(), TTAMachine::Machine::Navigator< ComponentType >::item(), LOCK_READ_, machine, TTAMachine::Component::name(), TRY_LOCK_ADDR_, and UNLOCK_ADDR_.

Referenced by ProGe::TestBenchBlock::TestBenchBlock().

Here is the call graph for this function:

◆ findWidestOperand()

unsigned MachineInfo::findWidestOperand ( const TTAMachine::Machine machine,
bool  vector 
)
static

Finds the widest operand available in the machine.

Helps finding the widest usable register in the machine.

Definition at line 566 of file MachineInfo.cc.

568 {
570 unsigned widestOperand = 0;
571
574
577 for (TCETools::CIStringSet::iterator it = opNames.begin();
578 it != opNames.end(); ++it) {
579
580 const Operation& op = pool.operation(it->c_str());
581
582 for (int j = 1; j < op.operandCount() + 1; ++j) {
583 if ((unsigned)(op.operand(j).width()) > widestOperand)
584 widestOperand = (unsigned)(op.operand(j).width());
585 }
586 }
587 return widestOperand;
588}
static OperationSet getOpset(const TTAMachine::Machine &mach)
virtual int width() const
Definition Operand.cc:318
TCETools::CIStringSet OperationSet
virtual int operandCount() const
Definition Operation.cc:212
virtual Operand & operand(int id) const
Definition Operation.cc:541
std::unique_ptr< OperationPool > pool

References TTAMachine::Machine::functionUnitNavigator(), getOpset(), machine, Operation::operand(), Operation::operandCount(), and Operand::width().

Referenced by llvm::TCEStubTTIImpl::getNumberOfRegisters(), and llvm::TCEStubTTIImpl::getRegisterBitWidth().

Here is the call graph for this function:

◆ getBoundPort()

const TTAMachine::FUPort * MachineInfo::getBoundPort ( const TTAMachine::FunctionUnit fu,
const std::string &  opName,
int  operandIndex 
)
static

Returns port that is bound to operand index of the operation in the FU.

Returns the port, if the FU has the operation and operation has the operand bound to some port. Otherwise, returns nullptr.

Definition at line 156 of file MachineInfo.cc.

158 {
159
160 if (fu.hasOperation(opName)) {
161 const HWOperation* hwOp = fu.operation(opName);
162 if (hwOp->isBound(operandIndex)) {
163 return hwOp->port(operandIndex);
164 }
165 }
166 return nullptr;
167}
virtual HWOperation * operation(const std::string &name) const
virtual FUPort * port(int operand) const
bool isBound(const FUPort &port) const

References TTAMachine::FunctionUnit::hasOperation(), TTAMachine::HWOperation::isBound(), TTAMachine::FunctionUnit::operation(), and TTAMachine::HWOperation::port().

Referenced by supportsBoolRegisterGuardedJumps(), supportsPortGuardedJump(), and supportsPortGuardedJumps().

Here is the call graph for this function:

◆ getOpset() [1/2]

OperationDAGSelector::OperationSet MachineInfo::getOpset ( const TTAMachine::ControlUnit gcu)
static

Returns opset used by Global Control Unit.

Parameters
gcuThe Global Control Unit whose opset is requested.
Returns
Opset used by the Global Control Unit.

Definition at line 93 of file MachineInfo.cc.

93 {
95 for (int i = 0; i < gcu.operationCount(); i++) {
96 const std::string opName = gcu.operation(i)->name();
97 opNames.insert(StringTools::stringToLower(opName));
98 }
99 return opNames;
100}
static std::string stringToLower(const std::string &source)
virtual int operationCount() const
const std::string & name() const

References TTAMachine::HWOperation::name(), TTAMachine::FunctionUnit::operation(), TTAMachine::FunctionUnit::operationCount(), and StringTools::stringToLower().

Here is the call graph for this function:

◆ getOpset() [2/2]

OperationDAGSelector::OperationSet MachineInfo::getOpset ( const TTAMachine::Machine mach)
static

Checks that the operands used in the operations of the given FU are bound to some port.

Parameters
machThe machine whose opset is requested.
Returns
Opset supported by machine hardware.

Definition at line 65 of file MachineInfo.cc.

65 {
66
68
71
72 OperationPool opPool;
73
74 for (int i = 0; i < fuNav.count(); i++) {
75 const TTAMachine::FunctionUnit* fu = fuNav.item(i);
76 for (int o = 0; o < fu->operationCount(); o++) {
77 const std::string opName = fu->operation(o)->name();
78 opNames.insert(StringTools::stringToLower(opName));
79 }
80 }
81
82 return opNames;
83}

References TTAMachine::Machine::Navigator< ComponentType >::count(), TTAMachine::Machine::functionUnitNavigator(), TTAMachine::Machine::Navigator< ComponentType >::item(), TTAMachine::HWOperation::name(), TTAMachine::FunctionUnit::operation(), TTAMachine::FunctionUnit::operationCount(), and StringTools::stringToLower().

Referenced by TTAProgram::CodeGenerator::CodeGenerator(), ProGe::CUOpcodeGenerator::encodings(), findWidestOperand(), TDGen::gatherAllMachineOperations(), DefaultICDecoderGenerator::generate(), ProGe::LoopBufferBlock::LoopBufferBlock(), supportsOperation(), DefaultDecoderGenerator::verifyCompatibility(), and TDGen::writeCondBranchDefs().

Here is the call graph for this function:

◆ getPortBindingsOfOperation()

MachineInfo::ConstPortList MachineInfo::getPortBindingsOfOperation ( const TTAMachine::Machine mach,
const std::string &  operationStr 
)
static

Return first occurrence of FUPorts that are bound to operation given by name.

Returned list has FUPorts ordered in the order of operands. At index 1 is port bounded to operand 1, at index 2 port bounded to operand 2 and so on. List is empty if operation was not found from machine. Unbounded operands have NULL at the index of operand (0 is always NULL).

Parameters
machThe machine.
operationStrThe operation.
Returns
The list of ordered bound ports.

Definition at line 117 of file MachineInfo.cc.

119 {
120
121 ConstPortList bindedPorts;
122
123 const TTAMachine::FunctionUnit* found = NULL;
126 for (int i = 0; i < fuNav.count(); i++) {
127 const TTAMachine::FunctionUnit* fu = fuNav.item(i);
128 if (fu->hasOperation(operationStr)) {
129 found = fu;
130 break;
131 }
132 }
133
134 if (found == NULL) {
135 if (mach.controlUnit()->hasOperation(operationStr)) {
136 found = mach.controlUnit();
137 }
138 }
139 if (found != NULL) {
140 bindedPorts.push_back(NULL); // Shift indexing.
141 HWOperation* operation = found->operation(operationStr);
142 for (int i = 1; i <= operation->operandCount(); i++) {
143 bindedPorts.push_back(operation->port(i));
144 }
145 }
146 return bindedPorts;
147}
std::vector< const TTAMachine::FUPort * > ConstPortList

References TTAMachine::Machine::controlUnit(), TTAMachine::Machine::Navigator< ComponentType >::count(), TTAMachine::Machine::functionUnitNavigator(), TTAMachine::FunctionUnit::hasOperation(), TTAMachine::Machine::Navigator< ComponentType >::item(), TTAMachine::HWOperation::operandCount(), TTAMachine::FunctionUnit::operation(), and TTAMachine::HWOperation::port().

Here is the call graph for this function:

◆ longestGuardLatency()

int MachineInfo::longestGuardLatency ( const TTAMachine::Machine mach)
static

Definition at line 202 of file MachineInfo.cc.

203 {
204 int ggLatency = mach.controlUnit()->globalGuardLatency();
205
207 mach.busNavigator();
208
209 for (int i = 0; i < busNav.count(); i++) {
210 const TTAMachine::Bus* bus = busNav.item(i);
211 for (int j = 0; j < bus->guardCount(); j++) {
212 Guard* guard = bus->guard(j);
213 RegisterGuard* rg = dynamic_cast<RegisterGuard*>(guard);
214 if (rg != NULL) {
215 int rgLat = rg->registerFile()->guardLatency();
216 if (rgLat != 0) {
217 assert(rgLat == 1);
218 return ggLatency + 1;
219 }
220 } else {
221 if (dynamic_cast<PortGuard*>(guard) != NULL) {
222 return ggLatency + 1;
223 }
224 }
225 }
226 }
227 return ggLatency;
228}
#define assert(condition)
Guard * guard(int index) const
Definition Bus.cc:456
int guardCount() const
Definition Bus.cc:441
int globalGuardLatency() const
virtual int guardLatency() const
const RegisterFile * registerFile() const

References assert, TTAMachine::Machine::busNavigator(), TTAMachine::Machine::controlUnit(), TTAMachine::Machine::Navigator< ComponentType >::count(), TTAMachine::ControlUnit::globalGuardLatency(), TTAMachine::Bus::guard(), TTAMachine::Bus::guardCount(), TTAMachine::RegisterFile::guardLatency(), TTAMachine::Machine::Navigator< ComponentType >::item(), and TTAMachine::RegisterGuard::registerFile().

Referenced by CompiledSimCodeGenerator::CompiledSimCodeGenerator().

Here is the call graph for this function:

◆ maxLatency()

int MachineInfo::maxLatency ( const TTAMachine::Machine mach,
TCEString opName 
)
static

Definition at line 806 of file MachineInfo.cc.

806 {
807 int maxl = -1;
808 for (auto fu: mach.functionUnitNavigator()) {
809 if (fu->hasOperation(opName)) {
810 const auto op = fu->operation(opName);
811 maxl = std::max(maxl, op->latency());
812 }
813 }
814 if (mach.controlUnit()->hasOperation(opName)) {
815 const auto op = mach.controlUnit()->operation(opName);
816 maxl = std::max(maxl, op->latency());
817 }
818 return maxl;
819}

References TTAMachine::Machine::controlUnit(), TTAMachine::Machine::functionUnitNavigator(), TTAMachine::FunctionUnit::hasOperation(), and TTAMachine::FunctionUnit::operation().

Referenced by ScheduleEstimator::maximumSizeOfBB().

Here is the call graph for this function:

◆ maxMemoryAlignment()

int MachineInfo::maxMemoryAlignment ( const TTAMachine::Machine mach)
static

Returns byte width of the widest load/store operation.

Returns
Maximum memory alignment according to the widest memory operation.

Definition at line 261 of file MachineInfo.cc.

261 {
262 int byteAlignment = 4; // Stack alignment is four bytes at minimum.
263
264 TTAMachine::FunctionUnit* fu = nullptr;
267 for (int i = 0; i < fuNav.count(); i++) {
268 fu = fuNav.item(i);
269 if (fu->hasAddressSpace()) {
270 if (fu->addressSpace()->hasNumericalId(0)) {
271 break;
272 }
273 }
274 }
275 assert(fu && "Didn't find the LSU with local AS");
276 for (int k = 0; k < fu->operationCount(); k++) {
277 TCEString operation = fu->operation(k)->name();
278
279 const TCEString opName = StringTools::stringToLower(operation);
280 if (opName.length() > 2 && isdigit(opName[2])) {
281 // Assume operations named ldNNxMM and stNNxMM are operations
282 // with alignment of NN (or ldNN / stNN).
283 // @todo fix this horrible hack by adding the alignment info explicitly
284 // to OSAL.
285
286 // At least check for the name string format to match the above
287 // before parsing the number.
288 size_t xpos = opName.find("x", 3);
289 if (xpos == std::string::npos) {
290 for (size_t pos = 2; pos < opName.size(); ++pos)
291 if (!isdigit(opName[pos])) continue;
292
293 if (opName.startsWith("ld")) {
294 int loadByteWidth = Conversion::toInt(opName.substr(2)) / 8;
295 if (loadByteWidth > byteAlignment) {
296 byteAlignment = loadByteWidth;
297 }
298 } else if (opName.startsWith("st")) {
299 int storeByteWidth = Conversion::toInt(opName.substr(2)) / 8;
300 if (storeByteWidth > byteAlignment) {
301 byteAlignment = storeByteWidth;
302 }
303 }
304 } else {
305 for (size_t pos = xpos + 1; pos < opName.size(); ++pos)
306 if (!isdigit(opName[pos])) continue;
307
308 if (opName.startsWith("ld")) {
309 int loadByteWidth = Conversion::toInt(opName.substr(2, xpos - 2)) / 8;
310 if (loadByteWidth > byteAlignment) {
311 byteAlignment = loadByteWidth;
312 }
313 } else if (opName.startsWith("st")) {
314 int storeByteWidth = Conversion::toInt(opName.substr(2, xpos - 2)) / 8;
315 if (storeByteWidth > byteAlignment) {
316 byteAlignment = storeByteWidth;
317 }
318 }
319 }
320 }
321 }
322
323 if (!(byteAlignment > 1 && !(byteAlignment & (byteAlignment - 1)))) {
324 std::cerr << "Stack alignment: " << byteAlignment << std::endl;
325 assert(false && "Error: stack alignment must be a power of 2.");
326 }
327
328 return byteAlignment;
329}
static int toInt(const T &source)
bool startsWith(const std::string &str) const
virtual bool hasNumericalId(unsigned id) const

References TTAMachine::FunctionUnit::addressSpace(), assert, TTAMachine::Machine::Navigator< ComponentType >::count(), TTAMachine::Machine::functionUnitNavigator(), TTAMachine::FunctionUnit::hasAddressSpace(), TTAMachine::AddressSpace::hasNumericalId(), TTAMachine::Machine::Navigator< ComponentType >::item(), TTAMachine::HWOperation::name(), TTAMachine::FunctionUnit::operation(), TTAMachine::FunctionUnit::operationCount(), TCEString::startsWith(), StringTools::stringToLower(), and Conversion::toInt().

Referenced by TTAProgram::CodeGenerator::CodeGenerator(), LLVMBackend::compile(), llvm::LLVMTCEBuilder::dataEnd(), and llvm::TCETargetMachine::setTargetMachinePlugin().

Here is the call graph for this function:

◆ numberOfRegisters()

unsigned MachineInfo::numberOfRegisters ( const TTAMachine::Machine machine,
unsigned  width 
)
static

Counts registers of given width.

Definition at line 594 of file MachineInfo.cc.

595 {
596
597 unsigned numRegisters = 0;
600
601 // Search register files of desired width and count registers
602 for (int i = 0; i < RFNavigator.count(); i++) {
603 TTAMachine::RegisterFile *rf = RFNavigator.item(i);
604 if ((unsigned)(rf->width()) == width) {
605 numRegisters += rf->size();
606 }
607 }
608 return numRegisters;
609}
virtual int size() const
virtual int width() const
virtual RegisterFileNavigator registerFileNavigator() const
Definition Machine.cc:450

References TTAMachine::Machine::Navigator< ComponentType >::count(), TTAMachine::Machine::Navigator< ComponentType >::item(), machine, TTAMachine::Machine::registerFileNavigator(), TTAMachine::BaseRegisterFile::size(), and TTAMachine::BaseRegisterFile::width().

Referenced by llvm::TCEStubTTIImpl::getNumberOfRegisters().

Here is the call graph for this function:

◆ operandFromPort()

Operand & MachineInfo::operandFromPort ( const TTAMachine::HWOperation hwOp,
const TTAMachine::FUPort port 
)
static

Returns Operand object for the given hardware operation attached to the port.

InstanceNotFound exception is thrown, if the hardware operation doesn't have an operand in the given port.

Parameters
hwOpHardware operation.
portThe port containing the desired Operand.
Returns
Reference to the Operand object.

Definition at line 241 of file MachineInfo.cc.

243 {
244
245 const TCEString& opName = hwOp.name();
246 OperationPool opPool;
247 const Operation& op = opPool.operation(opName.c_str());
248
249 assert(&op != &NullOperation::instance() && "Invalid operation name.");
250
251 int opndIndex = hwOp.io(port);
252 return op.operand(opndIndex);
253}
static NullOperation & instance()
Operation & operation(const char *name)
int io(const FUPort &port) const

References assert, NullOperation::instance(), TTAMachine::HWOperation::io(), TTAMachine::HWOperation::name(), Operation::operand(), and OperationPool::operation().

Here is the call graph for this function:

◆ osalOperation()

Operation & MachineInfo::osalOperation ( const TTAMachine::HWOperation hwOp)
static

Convenience function for getting OSAL operation from HWOperation description.

Throws InstanceNotFound if OSAL operation is not found.

Definition at line 794 of file MachineInfo.cc.

794 {
795 OperationPool opPool;
796
797 Operation& op = opPool.operation(hwOp.name().c_str());
798 if (op.isNull()) {
800 "Operation '" + hwOp.name() + "' was not found in OSAL.");
801 }
802 return op;
803}
#define THROW_EXCEPTION(exceptionType, message)
Exception wrapper macro that automatically includes file name, line number and function name where th...
Definition Exception.hh:39
bool isNull() const

References Operation::isNull(), TTAMachine::HWOperation::name(), OperationPool::operation(), and THROW_EXCEPTION.

Referenced by TDGen::supportedStackAccessOperations().

Here is the call graph for this function:

◆ portFromOperand()

template<typename PortType >
static PortType & MachineInfo::portFromOperand ( const TTAMachine::HWOperation hwOp,
const TTAMachine::FUPort port 
)
staticprivate

◆ supportsBoolRegisterGuardedJumps()

bool MachineInfo::supportsBoolRegisterGuardedJumps ( const TTAMachine::Machine machine)
static

Returns true if the machine has predicatable jump.

Definition at line 616 of file MachineInfo.cc.

617 {
618 const ControlUnit* cu = machine.controlUnit();
619 if (cu == nullptr) {
620 return false;
621 }
622
623 if (!cu->hasOperation("jump")) {
624 return false;
625 }
626
627 const FUPort* jumpPort = getBoundPort(*cu, "jump", 1);
628 if (jumpPort == nullptr) {
629 return false;
630 }
631
632 std::vector<const Bus*> guardedBuses;
633 for (const Bus* bus : machine.busNavigator()) {
634 for (int i = 0; i < bus->guardCount(); i++) {
635
636 const TTAMachine::RegisterGuard *regGuard =
637 dynamic_cast<TTAMachine::RegisterGuard*>(bus->guard(i));
638 if (regGuard && regGuard->registerFile()->width() == 1) {
639 guardedBuses.push_back(bus);
640 break;
641 }
642 }
643 }
644
645 for (const Bus* bus : guardedBuses) {
647 return true;
648 }
649 // Todo: Check if bus has sufficient transport capability for jumping?
650 // That is, it is at least connected to a RF, IU or can transport
651 // short immediates.
652 }
653
654 return false;
655}
static bool busConnectedToPort(const TTAMachine::Bus &bus, const TTAMachine::Port &port)
static const TTAMachine::FUPort * getBoundPort(const TTAMachine::FunctionUnit &fu, const std::string &opName, int operandIndex)

References MachineConnectivityCheck::busConnectedToPort(), TTAMachine::Machine::busNavigator(), TTAMachine::Machine::controlUnit(), getBoundPort(), TTAMachine::FunctionUnit::hasOperation(), machine, TTAMachine::RegisterGuard::registerFile(), and TTAMachine::BaseRegisterFile::width().

Referenced by TDGen::createBranchAnalysis(), llvm::TCETargetLowering::TCETargetLowering(), and TDGen::writeCondBranchDefs().

Here is the call graph for this function:

◆ supportsOperation()

bool MachineInfo::supportsOperation ( const TTAMachine::Machine mach,
TCEString  operation 
)
static

Definition at line 382 of file MachineInfo.cc.

383 {
386 return opNames.find(operation.upper()) != opNames.end();
387}
TCEString upper() const
Definition TCEString.cc:86

References getOpset(), and TCEString::upper().

Referenced by Peel2BBLoops::negateOp(), and ConstantTransformer::runOnMachineFunction().

Here is the call graph for this function:

◆ supportsPortGuardedJump()

bool MachineInfo::supportsPortGuardedJump ( const TTAMachine::Machine machine,
bool  inverted,
const TCEString opName 
)
static

Definition at line 703 of file MachineInfo.cc.

704 {
705
706 const ControlUnit* cu = machine.controlUnit();
707 if (cu == nullptr) {
708 return false;
709 }
710
711 if (!cu->hasOperation("jump")) {
712 return false;
713 }
714
715 const FUPort* jumpPort = getBoundPort(*cu, "jump", 1);
716 if (jumpPort == nullptr) {
717 return false;
718 }
719
720 std::vector<const Bus*> guardedBuses;
721 for (const Bus* bus : machine.busNavigator()) {
722 for (int i = 0; i < bus->guardCount(); i++) {
723 TTAMachine::Guard* guard = bus->guard(i);
724 if (guard->isInverted() != inverted) continue;
725 const TTAMachine::PortGuard *portGuard =
726 dynamic_cast<TTAMachine::PortGuard*>(guard);
727 if (portGuard) {
728 TTAMachine::FUPort* fup = portGuard->port();
729 auto fu = fup->parentUnit();
730 if (fu->hasOperation(opName)) {
731 // TODO: should check what ops found from the source FU
732 guardedBuses.push_back(bus);
733 }
734 }
735 }
736 }
737
738 for (const Bus* bus : guardedBuses) {
740 return true;
741 }
742 // Todo: Check if bus has sufficient transport capability for jumping?
743 // That is, it is at least connected to a RF, IU or can transport
744 // short immediates.
745 }
746
747 return false;
748}
FunctionUnit * parentUnit() const
Definition BaseFUPort.cc:96
virtual bool isInverted() const
FUPort * port() const

References MachineConnectivityCheck::busConnectedToPort(), TTAMachine::Machine::busNavigator(), TTAMachine::Machine::controlUnit(), getBoundPort(), TTAMachine::FunctionUnit::hasOperation(), TTAMachine::Guard::isInverted(), machine, TTAMachine::BaseFUPort::parentUnit(), and TTAMachine::PortGuard::port().

Referenced by TDGen::writeCondBranchDefs(), and TDGen::writePortGuardedJumpDefPair().

Here is the call graph for this function:

◆ supportsPortGuardedJumps()

bool MachineInfo::supportsPortGuardedJumps ( const TTAMachine::Machine machine)
static

Returns true if the machine has predicatable jump.

Definition at line 663 of file MachineInfo.cc.

663 {
664 const ControlUnit* cu = machine.controlUnit();
665 if (cu == nullptr) {
666 return false;
667 }
668
669 if (!cu->hasOperation("jump")) {
670 return false;
671 }
672
673 const FUPort* jumpPort = getBoundPort(*cu, "jump", 1);
674 if (jumpPort == nullptr) {
675 return false;
676 }
677
678 std::vector<const Bus*> guardedBuses;
679 for (const Bus* bus : machine.busNavigator()) {
680 for (int i = 0; i < bus->guardCount(); i++) {
681 const TTAMachine::PortGuard *portGuard =
682 dynamic_cast<TTAMachine::PortGuard*>(bus->guard(i));
683 if (portGuard) {
684 // TODO: should check what ops found from the source FU
685 guardedBuses.push_back(bus);
686 }
687 }
688 }
689
690 for (const Bus* bus : guardedBuses) {
692 return true;
693 }
694 // Todo: Check if bus has sufficient transport capability for jumping?
695 // That is, it is at least connected to a RF, IU or can transport
696 // short immediates.
697 }
698
699 return false;
700}

References MachineConnectivityCheck::busConnectedToPort(), TTAMachine::Machine::busNavigator(), TTAMachine::Machine::controlUnit(), getBoundPort(), TTAMachine::FunctionUnit::hasOperation(), and machine.

Referenced by TDGen::createBranchAnalysis(), llvm::TCETargetLowering::TCETargetLowering(), and TDGen::writeCondBranchDefs().

Here is the call graph for this function:

◆ templatesUsesSlot()

bool MachineInfo::templatesUsesSlot ( const TTAMachine::Machine mach,
const std::string &  slotName 
)
static

Checks if slot is used in any of the instruction templates defined in ADF.

Parameters
machThe Machine.
slotNameThe name of the slot.
Returns
True if any template includes given slot. False otherwise.

Definition at line 339 of file MachineInfo.cc.

341 {
342
343 std::set<InstructionTemplate*> affectingInstTemplates;
346 for (int i = 0; i < itNav.count(); i++) {
347 InstructionTemplate* iTemp = itNav.item(i);
348 if (iTemp->usesSlot(slotName)) {
349 return true;
350 }
351 }
352
353 return false;
354}
virtual bool usesSlot(const std::string &slotName) const
virtual InstructionTemplateNavigator instructionTemplateNavigator() const
Definition Machine.cc:428

References TTAMachine::Machine::Navigator< ComponentType >::count(), TTAMachine::Machine::instructionTemplateNavigator(), TTAMachine::Machine::Navigator< ComponentType >::item(), and TTAMachine::InstructionTemplate::usesSlot().

Here is the call graph for this function:

◆ templatesUsingSlot()

std::set< TTAMachine::InstructionTemplate * > MachineInfo::templatesUsingSlot ( const TTAMachine::Machine mach,
const std::string &  slotName 
)
static

Returns set of pointers to instruction templates that uses the given slot.

Parameters
machThe Machine.
slotNameThe name of the slot.
Returns
List of found templates or empty none was found.

Definition at line 365 of file MachineInfo.cc.

367 {
368 std::set<InstructionTemplate*> affectingInstTemplates;
371 for (int i = 0; i < itNav.count(); i++) {
372 InstructionTemplate* iTemp = itNav.item(i);
373 if (iTemp->usesSlot(slotName)) {
374 affectingInstTemplates.insert(iTemp);
375 }
376 }
377 return affectingInstTemplates;
378}

References TTAMachine::Machine::Navigator< ComponentType >::count(), TTAMachine::Machine::instructionTemplateNavigator(), TTAMachine::Machine::Navigator< ComponentType >::item(), and TTAMachine::InstructionTemplate::usesSlot().

Referenced by DefaultDecoderGenerator::writeSquashSignalGenerationProcess().

Here is the call graph for this function:

◆ triggerIndex() [1/2]

int MachineInfo::triggerIndex ( const TTAMachine::FunctionUnit fu,
const Operation op 
)
static

Definition at line 507 of file MachineInfo.cc.

508 {
509 if (fu.hasOperation(op.name())) {
511 fu.operation(op.name());
512 for (int j = 0; j < fu.operationPortCount(); j++) {
513 TTAMachine::FUPort* port = fu.operationPort(j);
514 if (port->isTriggering()) {
515 return hwop->io(*port);
516 }
517 }
518 }
519 // operation not found in this FU
520 return 0;
521}
virtual TCEString name() const
Definition Operation.cc:93
virtual bool isTriggering() const
Definition FUPort.cc:182
virtual FUPort * operationPort(const std::string &name) const
virtual int operationPortCount() const

References TTAMachine::FunctionUnit::hasOperation(), TTAMachine::HWOperation::io(), TTAMachine::FUPort::isTriggering(), Operation::name(), TTAMachine::FunctionUnit::operation(), TTAMachine::FunctionUnit::operationPort(), and TTAMachine::FunctionUnit::operationPortCount().

Here is the call graph for this function:

◆ triggerIndex() [2/2]

int MachineInfo::triggerIndex ( const TTAMachine::Machine machine,
const Operation op 
)
static

Finds the operand index of trigger of given operation in the machine.

If the operation is not found from the machine, return 0. If the index is ambiguos return -1.

Definition at line 530 of file MachineInfo.cc.

531 {
535 return op.numberOfInputs(); // last input
536 }
537 int index = 0;
538 for (int i = 0; i < nav.count(); i++) {
539 TTAMachine::FunctionUnit* fu = nav.item(i);
540 int curIndex = triggerIndex(*fu, op);
541 if (curIndex > 0) {
542 if (index > 0 && curIndex != index) {
543 return -1;
544 } else {
545 index = curIndex;
546 }
547 }
548 }
549 int curIndex = triggerIndex(*machine.controlUnit(), op);
550 if (curIndex > 0) {
551 if (index > 0 && curIndex != index) {
552 return -1;
553 } else {
554 index = curIndex;
555 }
556 }
557 return index;
558}
static int triggerIndex(const TTAMachine::Machine &machine, const Operation &op)
virtual int numberOfInputs() const
Definition Operation.cc:192
static UniversalMachine & instance()

References TTAMachine::Machine::controlUnit(), TTAMachine::Machine::Navigator< ComponentType >::count(), TTAMachine::Machine::functionUnitNavigator(), UniversalMachine::instance(), TTAMachine::Machine::Navigator< ComponentType >::item(), machine, Operation::numberOfInputs(), and triggerIndex().

Referenced by DataDependenceGraphBuilder::isTriggering(), and triggerIndex().

Here is the call graph for this function:

Member Data Documentation

◆ LOCK_READ_

const TCEString MachineInfo::LOCK_READ_ = "lock_read"
staticprivate

Definition at line 123 of file MachineInfo.hh.

Referenced by findLockUnits().

◆ TRY_LOCK_ADDR_

const TCEString MachineInfo::TRY_LOCK_ADDR_ = "try_lock_addr"
staticprivate

Definition at line 124 of file MachineInfo.hh.

Referenced by findLockUnits().

◆ UNLOCK_ADDR_

const TCEString MachineInfo::UNLOCK_ADDR_ = "unlock_addr"
staticprivate

Definition at line 125 of file MachineInfo.hh.

Referenced by findLockUnits().


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