1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
|
/* $Id: CodeContainer.hpp 4500 2009-04-21 15:53:26Z potyra $
*
* CodeContainer: can contain code and data and subcontainers.
*
* Copyright (C) 2008-2009 FAUmachine Team <info@faumachine.org>.
* This program is free software. You can redistribute it and/or modify it
* under the terms of the GNU General Public License, either version 2 of
* the License, or (at your option) any later version. See COPYING.
*/
#ifndef __CODE_CONTAINER_HPP_INCLUDED
#define __CODE_CONTAINER_HPP_INCLUDED
#include <list>
#include "intermediate/Node.hpp"
#include "intermediate/operands/RegisterFactory.hpp"
namespace intermediate {
//! can contain arbitrary seqences of code.
/** The CodeContainer can contain various intermediate code, and can be
* nested in itself.
* The text segment of a code container resembles exactly one function,
* which has the same name as the code container itself. The
* transfer segment denotes the parameters passed to the function.
* Subcontainers may denote other functions, which however may only
* be called from inside the container itself.
* The stack segment contains the locals of the funtion.
*/
class CodeContainer : public Node {
public:
enum DataModeE {
/** data should get added to the stack segment */
DATA_STACK,
/** data should get added to the transfer segment */
DATA_TRANSFER
};
//! c'tor
/** @param n name of the CodeContainer. The name of the
* code container can be used in call statements.
*/
CodeContainer(std::string n) : name(n),
dataMode(DATA_STACK),
regFab(RegisterFactory()) {}
//! Accept a Visitor.
/** All intermediate code nodes need to implement this method.
*
* @param v the Visitor that can visit this node.
*/
virtual void accept(Visitor& v) {
v.visit(*this);
}
//! add a child container.
/** @param n container to add.
*/
void addChild(CodeContainer *n) {
this->children.push_back(n);
}
//! add a piece of intermediate code to the container.
/** @param n node to add to the container.
*/
void addCode(Node *n) {
this->code.push_back(n);
}
//! add data to the container.
/** @param n data to add to the container.
*/
void addData(Node *n) {
switch (this->dataMode) {
case DATA_STACK:
this->stackData.push_back(n);
break;
case DATA_TRANSFER:
this->transferData.push_back(n);
break;
}
}
//! create a virtual register
/** @param type type of the virtual register operand
* @return newly created virtual register.
*/
Register*
createRegister(enum OpType type) {
return this->regFab.getReg(type);
}
/** return the number of virtual registers that are used by this
* CodeContainer.
* @return number of used virtual registers.
*/
unsigned int getNumUsedRegs(void) const {
return this->regFab.getNumUsedRegs();
}
/** child code containers. Will get evaluated *before* the current
* container. */
std::list<CodeContainer*> children;
/** data that should be stored on the local stack */
std::list<Node*> stackData;
/** transfer data (parameters) */
std::list<Node*> transferData;
//! code contained in the container.
std::list<Node*> code;
//! name of the container
std::string name;
//! default data mode
enum DataModeE dataMode;
//! associated RegisterFactory instance.
RegisterFactory regFab;
protected:
virtual ~CodeContainer() {}
};
}; /* namespace intermediate */
#endif /* __CODE_CONTAINER_HPP_INCLUDED */
|