mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-12 17:32:19 +00:00
Adding scheduling class.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@13783 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
4cffb588f5
commit
ebac64534c
183
lib/CodeGen/ModuloScheduling/MSSchedule.cpp
Normal file
183
lib/CodeGen/ModuloScheduling/MSSchedule.cpp
Normal file
@ -0,0 +1,183 @@
|
||||
//===-- MSSchedule.cpp Schedule ---------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file was developed by the LLVM research group and is distributed under
|
||||
// the University of Illinois Open Source License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
//
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#define DEBUG_TYPE "ModuloSched"
|
||||
|
||||
#include "MSSchedule.h"
|
||||
#include "Support/Debug.h"
|
||||
#include "llvm/Target/TargetSchedInfo.h"
|
||||
#include <iostream>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
bool MSSchedule::insert(MSchedGraphNode *node, int cycle) {
|
||||
|
||||
//First, check if the cycle has a spot free to start
|
||||
if(schedule.find(cycle) != schedule.end()) {
|
||||
if (schedule[cycle].size() < numIssue) {
|
||||
if(resourcesFree(node, cycle)) {
|
||||
schedule[cycle].push_back(node);
|
||||
DEBUG(std::cerr << "Found spot in map, and there is an issue slot\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
//Not in the map yet so put it in
|
||||
else {
|
||||
if(resourcesFree(node,cycle)) {
|
||||
std::vector<MSchedGraphNode*> nodes;
|
||||
nodes.push_back(node);
|
||||
schedule[cycle] = nodes;
|
||||
DEBUG(std::cerr << "Nothing in map yet so taking an issue slot\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG(std::cerr << "All issue slots taken\n");
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool MSSchedule::resourcesFree(MSchedGraphNode *node, int cycle) {
|
||||
|
||||
//Get Resource usage for this instruction
|
||||
const TargetSchedInfo & msi = node->getParent()->getTarget()->getSchedInfo();
|
||||
int currentCycle = cycle;
|
||||
bool success = true;
|
||||
|
||||
//Get resource usage for this instruction
|
||||
InstrRUsage rUsage = msi.getInstrRUsage(node->getInst()->getOpcode());
|
||||
std::vector<std::vector<resourceId_t> > resources = rUsage.resourcesByCycle;
|
||||
|
||||
//Loop over resources in each cycle and increments their usage count
|
||||
for(unsigned i=0; i < resources.size(); ++i) {
|
||||
for(unsigned j=0; j < resources[i].size(); ++j) {
|
||||
int resourceNum = resources[i][j];
|
||||
|
||||
//Check if this resource is available for this cycle
|
||||
std::map<int, std::map<int,int> >::iterator resourcesForCycle = resourceNumPerCycle.find(currentCycle);
|
||||
|
||||
//First check map of resources for this cycle
|
||||
if(resourcesForCycle != resourceNumPerCycle.end()) {
|
||||
//A map exists for this cycle, so lets check for the resource
|
||||
std::map<int, int>::iterator resourceUse = resourcesForCycle->second.find(resourceNum);
|
||||
if(resourceUse != resourcesForCycle->second.end()) {
|
||||
//Check if there are enough of this resource and if so, increase count and move on
|
||||
if(resourceUse->second < CPUResource::getCPUResource(resourceNum)->maxNumUsers)
|
||||
++resourceUse->second;
|
||||
else {
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
//Not in the map yet, so put it
|
||||
else
|
||||
resourcesForCycle->second[resourceNum] = 1;
|
||||
|
||||
}
|
||||
else {
|
||||
//Create a new map and put in our resource
|
||||
std::map<int, int> resourceMap;
|
||||
resourceMap[resourceNum] = 1;
|
||||
resourceNumPerCycle[cycle] = resourceMap;
|
||||
}
|
||||
if(!success)
|
||||
break;
|
||||
}
|
||||
if(!success)
|
||||
break;
|
||||
//Increase cycle
|
||||
currentCycle++;
|
||||
}
|
||||
|
||||
if(!success) {
|
||||
int oldCycle = cycle;
|
||||
DEBUG(std::cerr << "Backtrack\n");
|
||||
//Get resource usage for this instruction
|
||||
InstrRUsage rUsage = msi.getInstrRUsage(node->getInst()->getOpcode());
|
||||
std::vector<std::vector<resourceId_t> > resources = rUsage.resourcesByCycle;
|
||||
|
||||
//Loop over resources in each cycle and increments their usage count
|
||||
for(unsigned i=0; i < resources.size(); ++i) {
|
||||
if(oldCycle < currentCycle) {
|
||||
|
||||
//Check if this resource is available for this cycle
|
||||
std::map<int, std::map<int,int> >::iterator resourcesForCycle = resourceNumPerCycle.find(oldCycle);
|
||||
|
||||
for(unsigned j=0; j < resources[i].size(); ++j) {
|
||||
int resourceNum = resources[i][j];
|
||||
//remove from map
|
||||
std::map<int, int>::iterator resourceUse = resourcesForCycle->second.find(resourceNum);
|
||||
//assert if not in the map.. since it should be!
|
||||
//assert(resourceUse != resourcesForCycle.end() && "Resource should be in map!");
|
||||
--resourceUse->second;
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
oldCycle++;
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool MSSchedule::constructKernel(int II) {
|
||||
MSchedGraphNode *branchNode;
|
||||
|
||||
int stageNum = (schedule.rbegin()->first)/ II;
|
||||
DEBUG(std::cerr << "Number of Stages: " << stageNum << "\n");
|
||||
|
||||
for(int index = 0; index < II; ++index) {
|
||||
int count = 0;
|
||||
for(int i = index; i <= (schedule.rbegin()->first); i+=II) {
|
||||
if(schedule.count(i)) {
|
||||
for(std::vector<MSchedGraphNode*>::iterator I = schedule[i].begin(),
|
||||
E = schedule[i].end(); I != E; ++I) {
|
||||
//Check if its a branch
|
||||
if((*I)->isBranch()) {
|
||||
branchNode = *I;
|
||||
assert(count == 0 && "Branch can not be from a previous iteration");
|
||||
}
|
||||
else
|
||||
//FIXME: Check if the instructions in the earlier stage conflict
|
||||
kernel.push_back(std::make_pair(*I, count));
|
||||
}
|
||||
}
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
//Add Branch to the end
|
||||
kernel.push_back(std::make_pair(branchNode, 0));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void MSSchedule::print(std::ostream &os) const {
|
||||
os << "Schedule:\n";
|
||||
|
||||
for(schedule_const_iterator I = schedule.begin(), E = schedule.end(); I != E; ++I) {
|
||||
os << "Cycle: " << I->first << "\n";
|
||||
for(std::vector<MSchedGraphNode*>::const_iterator node = I->second.begin(), nodeEnd = I->second.end(); node != nodeEnd; ++node)
|
||||
os << **node << "\n";
|
||||
}
|
||||
|
||||
os << "Kernel:\n";
|
||||
for(std::vector<std::pair<MSchedGraphNode*, int> >::const_iterator I = kernel.begin(),
|
||||
E = kernel.end(); I != E; ++I)
|
||||
os << "Node: " << *(I->first) << " Stage: " << I->second << "\n";
|
||||
}
|
||||
|
63
lib/CodeGen/ModuloScheduling/MSSchedule.h
Normal file
63
lib/CodeGen/ModuloScheduling/MSSchedule.h
Normal file
@ -0,0 +1,63 @@
|
||||
//===-- MSSchedule.h - Schedule ------- -------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file was developed by the LLVM research group and is distributed under
|
||||
// the University of Illinois Open Source License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The schedule generated by a scheduling algorithm
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_MSSCHEDULE_H
|
||||
#define LLVM_MSSCHEDULE_H
|
||||
|
||||
#include "MSchedGraph.h"
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class MSSchedule {
|
||||
std::map<int, std::vector<MSchedGraphNode*> > schedule;
|
||||
unsigned numIssue;
|
||||
|
||||
//Internal map to keep track of explicit resources
|
||||
std::map<int, std::map<int, int> > resourceNumPerCycle;
|
||||
|
||||
//Check if all resources are free
|
||||
bool resourcesFree(MSchedGraphNode*, int);
|
||||
|
||||
//Resulting kernel
|
||||
std::vector<std::pair<MSchedGraphNode*, int> > kernel;
|
||||
|
||||
public:
|
||||
MSSchedule(int num) : numIssue(num) {}
|
||||
MSSchedule() : numIssue(4) {}
|
||||
bool insert(MSchedGraphNode *node, int cycle);
|
||||
int getStartCycle(MSchedGraphNode *node);
|
||||
void clear() { schedule.clear(); resourceNumPerCycle.clear(); kernel.clear(); }
|
||||
std::vector<std::pair<MSchedGraphNode*, int> >* getKernel() { return &kernel; }
|
||||
bool constructKernel(int II);
|
||||
|
||||
|
||||
|
||||
//iterators
|
||||
typedef std::map<int, std::vector<MSchedGraphNode*> >::iterator schedule_iterator;
|
||||
typedef std::map<int, std::vector<MSchedGraphNode*> >::const_iterator schedule_const_iterator;
|
||||
schedule_iterator begin() { return schedule.begin(); };
|
||||
schedule_iterator end() { return schedule.end(); };
|
||||
void print(std::ostream &os) const;
|
||||
|
||||
typedef std::vector<std::pair<MSchedGraphNode*, int> >::iterator kernel_iterator;
|
||||
typedef std::vector<std::pair<MSchedGraphNode*, int> >::const_iterator kernel_const_iterator;
|
||||
kernel_iterator kernel_begin() { return kernel.begin(); }
|
||||
kernel_iterator kernel_end() { return kernel.end(); }
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
183
lib/Target/SparcV9/ModuloScheduling/MSSchedule.cpp
Normal file
183
lib/Target/SparcV9/ModuloScheduling/MSSchedule.cpp
Normal file
@ -0,0 +1,183 @@
|
||||
//===-- MSSchedule.cpp Schedule ---------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file was developed by the LLVM research group and is distributed under
|
||||
// the University of Illinois Open Source License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
//
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#define DEBUG_TYPE "ModuloSched"
|
||||
|
||||
#include "MSSchedule.h"
|
||||
#include "Support/Debug.h"
|
||||
#include "llvm/Target/TargetSchedInfo.h"
|
||||
#include <iostream>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
bool MSSchedule::insert(MSchedGraphNode *node, int cycle) {
|
||||
|
||||
//First, check if the cycle has a spot free to start
|
||||
if(schedule.find(cycle) != schedule.end()) {
|
||||
if (schedule[cycle].size() < numIssue) {
|
||||
if(resourcesFree(node, cycle)) {
|
||||
schedule[cycle].push_back(node);
|
||||
DEBUG(std::cerr << "Found spot in map, and there is an issue slot\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
//Not in the map yet so put it in
|
||||
else {
|
||||
if(resourcesFree(node,cycle)) {
|
||||
std::vector<MSchedGraphNode*> nodes;
|
||||
nodes.push_back(node);
|
||||
schedule[cycle] = nodes;
|
||||
DEBUG(std::cerr << "Nothing in map yet so taking an issue slot\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG(std::cerr << "All issue slots taken\n");
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool MSSchedule::resourcesFree(MSchedGraphNode *node, int cycle) {
|
||||
|
||||
//Get Resource usage for this instruction
|
||||
const TargetSchedInfo & msi = node->getParent()->getTarget()->getSchedInfo();
|
||||
int currentCycle = cycle;
|
||||
bool success = true;
|
||||
|
||||
//Get resource usage for this instruction
|
||||
InstrRUsage rUsage = msi.getInstrRUsage(node->getInst()->getOpcode());
|
||||
std::vector<std::vector<resourceId_t> > resources = rUsage.resourcesByCycle;
|
||||
|
||||
//Loop over resources in each cycle and increments their usage count
|
||||
for(unsigned i=0; i < resources.size(); ++i) {
|
||||
for(unsigned j=0; j < resources[i].size(); ++j) {
|
||||
int resourceNum = resources[i][j];
|
||||
|
||||
//Check if this resource is available for this cycle
|
||||
std::map<int, std::map<int,int> >::iterator resourcesForCycle = resourceNumPerCycle.find(currentCycle);
|
||||
|
||||
//First check map of resources for this cycle
|
||||
if(resourcesForCycle != resourceNumPerCycle.end()) {
|
||||
//A map exists for this cycle, so lets check for the resource
|
||||
std::map<int, int>::iterator resourceUse = resourcesForCycle->second.find(resourceNum);
|
||||
if(resourceUse != resourcesForCycle->second.end()) {
|
||||
//Check if there are enough of this resource and if so, increase count and move on
|
||||
if(resourceUse->second < CPUResource::getCPUResource(resourceNum)->maxNumUsers)
|
||||
++resourceUse->second;
|
||||
else {
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
//Not in the map yet, so put it
|
||||
else
|
||||
resourcesForCycle->second[resourceNum] = 1;
|
||||
|
||||
}
|
||||
else {
|
||||
//Create a new map and put in our resource
|
||||
std::map<int, int> resourceMap;
|
||||
resourceMap[resourceNum] = 1;
|
||||
resourceNumPerCycle[cycle] = resourceMap;
|
||||
}
|
||||
if(!success)
|
||||
break;
|
||||
}
|
||||
if(!success)
|
||||
break;
|
||||
//Increase cycle
|
||||
currentCycle++;
|
||||
}
|
||||
|
||||
if(!success) {
|
||||
int oldCycle = cycle;
|
||||
DEBUG(std::cerr << "Backtrack\n");
|
||||
//Get resource usage for this instruction
|
||||
InstrRUsage rUsage = msi.getInstrRUsage(node->getInst()->getOpcode());
|
||||
std::vector<std::vector<resourceId_t> > resources = rUsage.resourcesByCycle;
|
||||
|
||||
//Loop over resources in each cycle and increments their usage count
|
||||
for(unsigned i=0; i < resources.size(); ++i) {
|
||||
if(oldCycle < currentCycle) {
|
||||
|
||||
//Check if this resource is available for this cycle
|
||||
std::map<int, std::map<int,int> >::iterator resourcesForCycle = resourceNumPerCycle.find(oldCycle);
|
||||
|
||||
for(unsigned j=0; j < resources[i].size(); ++j) {
|
||||
int resourceNum = resources[i][j];
|
||||
//remove from map
|
||||
std::map<int, int>::iterator resourceUse = resourcesForCycle->second.find(resourceNum);
|
||||
//assert if not in the map.. since it should be!
|
||||
//assert(resourceUse != resourcesForCycle.end() && "Resource should be in map!");
|
||||
--resourceUse->second;
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
oldCycle++;
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool MSSchedule::constructKernel(int II) {
|
||||
MSchedGraphNode *branchNode;
|
||||
|
||||
int stageNum = (schedule.rbegin()->first)/ II;
|
||||
DEBUG(std::cerr << "Number of Stages: " << stageNum << "\n");
|
||||
|
||||
for(int index = 0; index < II; ++index) {
|
||||
int count = 0;
|
||||
for(int i = index; i <= (schedule.rbegin()->first); i+=II) {
|
||||
if(schedule.count(i)) {
|
||||
for(std::vector<MSchedGraphNode*>::iterator I = schedule[i].begin(),
|
||||
E = schedule[i].end(); I != E; ++I) {
|
||||
//Check if its a branch
|
||||
if((*I)->isBranch()) {
|
||||
branchNode = *I;
|
||||
assert(count == 0 && "Branch can not be from a previous iteration");
|
||||
}
|
||||
else
|
||||
//FIXME: Check if the instructions in the earlier stage conflict
|
||||
kernel.push_back(std::make_pair(*I, count));
|
||||
}
|
||||
}
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
//Add Branch to the end
|
||||
kernel.push_back(std::make_pair(branchNode, 0));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void MSSchedule::print(std::ostream &os) const {
|
||||
os << "Schedule:\n";
|
||||
|
||||
for(schedule_const_iterator I = schedule.begin(), E = schedule.end(); I != E; ++I) {
|
||||
os << "Cycle: " << I->first << "\n";
|
||||
for(std::vector<MSchedGraphNode*>::const_iterator node = I->second.begin(), nodeEnd = I->second.end(); node != nodeEnd; ++node)
|
||||
os << **node << "\n";
|
||||
}
|
||||
|
||||
os << "Kernel:\n";
|
||||
for(std::vector<std::pair<MSchedGraphNode*, int> >::const_iterator I = kernel.begin(),
|
||||
E = kernel.end(); I != E; ++I)
|
||||
os << "Node: " << *(I->first) << " Stage: " << I->second << "\n";
|
||||
}
|
||||
|
63
lib/Target/SparcV9/ModuloScheduling/MSSchedule.h
Normal file
63
lib/Target/SparcV9/ModuloScheduling/MSSchedule.h
Normal file
@ -0,0 +1,63 @@
|
||||
//===-- MSSchedule.h - Schedule ------- -------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file was developed by the LLVM research group and is distributed under
|
||||
// the University of Illinois Open Source License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The schedule generated by a scheduling algorithm
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_MSSCHEDULE_H
|
||||
#define LLVM_MSSCHEDULE_H
|
||||
|
||||
#include "MSchedGraph.h"
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class MSSchedule {
|
||||
std::map<int, std::vector<MSchedGraphNode*> > schedule;
|
||||
unsigned numIssue;
|
||||
|
||||
//Internal map to keep track of explicit resources
|
||||
std::map<int, std::map<int, int> > resourceNumPerCycle;
|
||||
|
||||
//Check if all resources are free
|
||||
bool resourcesFree(MSchedGraphNode*, int);
|
||||
|
||||
//Resulting kernel
|
||||
std::vector<std::pair<MSchedGraphNode*, int> > kernel;
|
||||
|
||||
public:
|
||||
MSSchedule(int num) : numIssue(num) {}
|
||||
MSSchedule() : numIssue(4) {}
|
||||
bool insert(MSchedGraphNode *node, int cycle);
|
||||
int getStartCycle(MSchedGraphNode *node);
|
||||
void clear() { schedule.clear(); resourceNumPerCycle.clear(); kernel.clear(); }
|
||||
std::vector<std::pair<MSchedGraphNode*, int> >* getKernel() { return &kernel; }
|
||||
bool constructKernel(int II);
|
||||
|
||||
|
||||
|
||||
//iterators
|
||||
typedef std::map<int, std::vector<MSchedGraphNode*> >::iterator schedule_iterator;
|
||||
typedef std::map<int, std::vector<MSchedGraphNode*> >::const_iterator schedule_const_iterator;
|
||||
schedule_iterator begin() { return schedule.begin(); };
|
||||
schedule_iterator end() { return schedule.end(); };
|
||||
void print(std::ostream &os) const;
|
||||
|
||||
typedef std::vector<std::pair<MSchedGraphNode*, int> >::iterator kernel_iterator;
|
||||
typedef std::vector<std::pair<MSchedGraphNode*, int> >::const_iterator kernel_const_iterator;
|
||||
kernel_iterator kernel_begin() { return kernel.begin(); }
|
||||
kernel_iterator kernel_end() { return kernel.end(); }
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user