Exemplo n.º 1
0
static StringVector getAllSymbolsUsedByThisKernel(
	const std::string& kernelName, ir::Module* module)
{
	auto kernel = module->kernels().find(kernelName);

	if(kernel == module->kernels().end()) return StringVector();
	
	StringSet encountered;
	
	for(auto block = kernel->second->cfg()->begin();
		block != kernel->second->cfg()->end(); ++block)
	{
		for(auto instruction = block->instructions.begin();
			instruction != block->instructions.end(); ++instruction)
		{
			typedef std::vector<ir::PTXOperand*> OperandVector;
			
			auto ptx = static_cast<ir::PTXInstruction*>(*instruction);
		
			OperandVector operands;
			
			operands.push_back(&ptx->a);
			operands.push_back(&ptx->b);
			operands.push_back(&ptx->pg);
			operands.push_back(&ptx->pq);
			operands.push_back(&ptx->d);
			
			if(ptx->opcode != ir::PTXInstruction::Call)
			{
				 operands.push_back(&ptx->c);
			}
		
			for(auto operand = operands.begin();
				operand != operands.end(); ++operand)
			{
				if((*operand)->addressMode != ir::PTXOperand::Address &&
					(*operand)->addressMode != ir::PTXOperand::FunctionName)
				{
					continue;
				}
				
				encountered.insert((*operand)->identifier);
			}
		}
	}
	
	return StringVector(encountered.begin(), encountered.end());
}
Exemplo n.º 2
0
static void replaceInstances(ir::Module& module, const std::string& oldName,
	const std::string& newName)
{
	for(auto kernel = module.kernels().begin();
		kernel != module.kernels().end(); ++kernel)
	{
		for(auto block = kernel->second->cfg()->begin();
			block != kernel->second->cfg()->end(); ++block)
		{
			for(auto instruction = block->instructions.begin();
				instruction != block->instructions.end(); ++instruction)
			{
				typedef std::vector<ir::PTXOperand*> OperandVector;
				
				auto ptx = static_cast<ir::PTXInstruction*>(*instruction);
			
				OperandVector operands;
				
				operands.push_back(&ptx->a);
				operands.push_back(&ptx->b);
				operands.push_back(&ptx->pg);
				operands.push_back(&ptx->pq);
				operands.push_back(&ptx->d);
				
				if(ptx->opcode != ir::PTXInstruction::Call)
				{
					 operands.push_back(&ptx->c);
				}
				
				for(auto operand = operands.begin();
					operand != operands.end(); ++operand)
				{
					if((*operand)->addressMode != ir::PTXOperand::Address)
					{
						continue;
					}
					
					if((*operand)->identifier == oldName)
					{
						(*operand)->identifier = newName;
					}
				}
			}
		}
	}
}
	void ATIExecutableKernel::initializeSharedMemory()
	{
		report("Allocating shared memory");

		typedef std::unordered_map<std::string, size_t> AllocationMap;
		typedef std::unordered_set<std::string> StringSet;
		typedef std::deque<ir::PTXOperand*> OperandVector;
		typedef std::unordered_map<std::string,
				ir::Module::GlobalMap::const_iterator> GlobalMap;

		AllocationMap map;
		GlobalMap sharedGlobals;
		StringSet external;
		OperandVector externalOperands;

		unsigned int externalAlignment = 1;
		size_t sharedSize = 0;

		assert(module != 0);

		// global shared variables
		ir::Module::GlobalMap globals = module->globals();
		ir::Module::GlobalMap::const_iterator global;
		for (global = globals.begin() ; global != globals.end() ; global++)
		{
			ir::PTXStatement statement = global->second.statement;
			if (statement.directive == ir::PTXStatement::Shared)
			{
				if (statement.attribute == ir::PTXStatement::Extern)
				{
					report("Found global external shared variable \""
							<< statement.name << "\"");

					assertM(external.count(statement.name) == 0,
							"External global \"" << statement.name
							<< "\" declared more than once.");

					external.insert(statement.name);
					externalAlignment = std::max(externalAlignment,
							(unsigned int)statement.alignment);
					externalAlignment = std::max(externalAlignment,
							ir::PTXOperand::bytes(statement.type));
				} else {
					report("Found global shared variable \"" 
							<< statement.name << "\"");
					sharedGlobals.insert(
							std::make_pair(statement.name, global));
				}
			}
		}

		// local shared variables	
		LocalMap::const_iterator local;
		for (local = locals.begin() ; local != locals.end() ; local++)
		{
			if (local->second.space == ir::PTXInstruction::Shared)
			{
				if (local->second.attribute == ir::PTXStatement::Extern)
				{
					report("Found local external shared variable \"" 
							<< local->second.name << "\"");

					assertM(external.count(local->second.name) == 0,
							"External local \"" << local->second.name
							<< "\" declared more than once.");

					external.insert(local->second.name);
					externalAlignment = std::max(externalAlignment,
							(unsigned int)local->second.alignment);
					externalAlignment = std::max(externalAlignment,
							ir::PTXOperand::bytes(local->second.type));
				} else
				{
					report("Allocating local shared variable \""
							<< local->second.name << "\" of size "
							<< local->second.getSize());

					_pad(sharedSize, local->second.alignment);
					map.insert(std::make_pair(local->second.name, sharedSize));
					sharedSize += local->second.getSize();
				}
			}
		}

		ir::ControlFlowGraph::iterator block;
		for (block = cfg()->begin() ; block != cfg()->end() ; block++)
		{
			ir::ControlFlowGraph::InstructionList insts = block->instructions;
			ir::ControlFlowGraph::InstructionList::iterator inst;
			for (inst = insts.begin() ; inst != insts.end() ; inst++)
			{
				ir::PTXInstruction& ptx = 
					static_cast<ir::PTXInstruction&>(**inst);

				if (ptx.opcode == ir::PTXInstruction::Mov ||
						ptx.opcode == ir::PTXInstruction::Ld ||
						ptx.opcode == ir::PTXInstruction::St)
				{
					ir::PTXOperand* operands[] = {&ptx.d, &ptx.a, &ptx.b, 
						&ptx.c};

					for (unsigned int i = 0 ; i != 4 ; i++)
					{
						ir::PTXOperand* operand = operands[i];

						if (operand->addressMode == ir::PTXOperand::Address)
						{
							StringSet::iterator si = 
								external.find(operand->identifier);
							if (si != external.end())
							{
								report("For instruction \""
										<< ptx.toString()
										<< "\", mapping shared label \"" << *si
										<< "\" to external shared memory.");
								externalOperands.push_back(operand);
								continue;
							}

							GlobalMap::iterator gi = 
								sharedGlobals.find(operand->identifier);
							if (gi != sharedGlobals.end())
							{
								ir::Module::GlobalMap::const_iterator it = 
									gi->second;
								sharedGlobals.erase(gi);

								report("Allocating global shared variable \""
										<< it->second.statement.name << "\"");

								map.insert(std::make_pair(
											it->second.statement.name, 
											sharedSize));
								sharedSize += it->second.statement.bytes();
							}

							AllocationMap::iterator mapping = 
								map.find(operand->identifier);
							if (mapping != map.end())
							{
								report("For instruction " << ptx.toString()
										<< ", mapping shared label "
										<< mapping->first << " to " << 
										mapping->second);

								operand->addressMode = 
									ir::PTXOperand::Immediate;
								operand->imm_uint = mapping->second;
							}
						}
					}
				}
			}
		}

		_pad(sharedSize, externalAlignment);

		report("Mapping external shared variables.");
		OperandVector::iterator operand;
		for (operand = externalOperands.begin() ; 
				operand != externalOperands.end() ; operand++)
		{
			report("Mapping external shared label \""
					<< (*operand)->identifier << "\" to " << sharedSize);
			(*operand)->addressMode = ir::PTXOperand::Immediate;
			(*operand)->imm_uint = sharedSize;
		}

		// allocate shared memory object
		_sharedMemorySize = sharedSize;

		report("Total shared memory size is " << _sharedMemorySize);
	}