Compare commits
2 Commits
PARTYTOOL1
...
regalloc_c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1c43d4984f | ||
|
|
cfe021ff88 |
134
mozilla/ef/Compiler/RegisterAllocator/BitSet.cpp
Normal file
134
mozilla/ef/Compiler/RegisterAllocator/BitSet.cpp
Normal file
@@ -0,0 +1,134 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "BitSet.h"
|
||||
|
||||
// Return the next bit after index set to true or -1 if none.
|
||||
//
|
||||
Int32 BitSet::nextOne(Int32 pos) const
|
||||
{
|
||||
++pos;
|
||||
|
||||
if (pos < 0 || Uint32(pos) >= universeSize)
|
||||
return -1;
|
||||
|
||||
Uint32 offset = getWordOffset(pos);
|
||||
Uint8 index = getBitOffset(pos);
|
||||
Word* ptr = &word[offset];
|
||||
Word currentWord = *ptr++ >> index;
|
||||
|
||||
if (currentWord != Word(0)) {
|
||||
while ((currentWord & Word(1)) == 0) {
|
||||
++index;
|
||||
currentWord >>= 1;
|
||||
}
|
||||
return (offset << nBitsInWordLog2) + index;
|
||||
}
|
||||
|
||||
Word* limit = &word[getSizeInWords(universeSize)];
|
||||
while (ptr < limit) {
|
||||
++offset;
|
||||
currentWord = *ptr++;
|
||||
if (currentWord != Word(0)) {
|
||||
index = 0;
|
||||
while ((currentWord & Word(1)) == 0) {
|
||||
++index;
|
||||
currentWord >>= 1;
|
||||
}
|
||||
return (offset << nBitsInWordLog2) + index;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Return the next bit after index set to false or -1 if none.
|
||||
//
|
||||
Int32 BitSet::nextZero(Int32 pos) const
|
||||
{
|
||||
++pos;
|
||||
|
||||
if (pos < 0 || Uint32(pos) >= universeSize)
|
||||
return -1;
|
||||
|
||||
Uint32 offset = getWordOffset(pos);
|
||||
Uint8 index = getBitOffset(pos);
|
||||
Word* ptr = &word[offset];
|
||||
Word currentWord = *ptr++ >> index;
|
||||
|
||||
if (currentWord != Word(~0)) {
|
||||
for (; index < nBitsInWord; ++index) {
|
||||
if ((currentWord & Word(1)) == 0) {
|
||||
Int32 ret = (offset << nBitsInWordLog2) + index;
|
||||
return (Uint32(ret) < universeSize) ? ret : -1;
|
||||
}
|
||||
currentWord >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
Word* limit = &word[getSizeInWords(universeSize)];
|
||||
while (ptr < limit) {
|
||||
++offset;
|
||||
currentWord = *ptr++;
|
||||
if (currentWord != Word(~0)) {
|
||||
for (index = 0; index < nBitsInWord; ++index) {
|
||||
if ((currentWord & Word(1)) == 0) {
|
||||
Int32 ret = (offset << nBitsInWordLog2) + index;
|
||||
return (Uint32(ret) < universeSize) ? ret : -1;
|
||||
}
|
||||
currentWord >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
|
||||
// Print the set.
|
||||
//
|
||||
void BitSet::printPretty(LogModuleObject log)
|
||||
{
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("[ "));
|
||||
|
||||
for (Int32 i = firstOne(); i != -1; i = nextOne(i)) {
|
||||
Int32 currentBit = i;
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("%d", currentBit));
|
||||
|
||||
Int32 nextBit = nextOne(currentBit);
|
||||
if (nextBit != currentBit + 1) {
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, (" "));
|
||||
continue;
|
||||
}
|
||||
|
||||
while ((nextBit != -1) && (nextBit == (currentBit + 1))) {
|
||||
currentBit = nextBit;
|
||||
nextBit = nextOne(nextBit);
|
||||
}
|
||||
|
||||
if (currentBit > (i+1))
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("-%d ", currentBit));
|
||||
else
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, (" %d ", currentBit));
|
||||
|
||||
i = currentBit;
|
||||
}
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("]\n"));
|
||||
}
|
||||
|
||||
#endif // DEBUG_LOG
|
||||
195
mozilla/ef/Compiler/RegisterAllocator/BitSet.h
Normal file
195
mozilla/ef/Compiler/RegisterAllocator/BitSet.h
Normal file
@@ -0,0 +1,195 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _BITSET_H_
|
||||
#define _BITSET_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "LogModule.h"
|
||||
#include "Pool.h"
|
||||
#include <string.h>
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// BitSet -
|
||||
|
||||
class BitSet
|
||||
{
|
||||
private:
|
||||
|
||||
#if (PR_BITS_PER_WORD == 64)
|
||||
typedef Uint64 Word;
|
||||
#elif (PR_BITS_PER_WORD == 32)
|
||||
typedef Uint32 Word;
|
||||
#endif
|
||||
|
||||
static const nBitsInWord = PR_BITS_PER_WORD;
|
||||
static const nBytesInWord = PR_BYTES_PER_WORD;
|
||||
static const nBitsInWordLog2 = PR_BITS_PER_WORD_LOG2;
|
||||
static const nBytesInWordLog2 = PR_BYTES_PER_WORD_LOG2;
|
||||
|
||||
// Return the number of Word need to store the universe.
|
||||
static Uint32 getSizeInWords(Uint32 sizeOfUniverse) {return (sizeOfUniverse + (nBitsInWord - 1)) >> nBitsInWordLog2;}
|
||||
// Return the given element offset in its containing Word.
|
||||
static Uint32 getBitOffset(Uint32 element) {return element & (nBitsInWord - 1);}
|
||||
// Return the Word offset for the given element int the universe.
|
||||
static Uint32 getWordOffset(Uint32 element) {return element >> nBitsInWordLog2;}
|
||||
// Return the mask for the given bit index.
|
||||
static Word getMask(Uint8 index) {return Word(1) << index;}
|
||||
|
||||
private:
|
||||
|
||||
Uint32 universeSize; // Size of the universe
|
||||
Word* word; // universe memory.
|
||||
|
||||
private:
|
||||
|
||||
// No copy constructor.
|
||||
BitSet(const BitSet&);
|
||||
|
||||
// Check if the given set's universe is of the same size than this universe.
|
||||
void checkUniverseCompatibility(const BitSet& set) const {assert(set.universeSize == universeSize);}
|
||||
// Check if pos is valid for this set's universe.
|
||||
void checkMember(Int32 pos) const {assert(pos >=0 && Uint32(pos) < universeSize);}
|
||||
|
||||
public:
|
||||
|
||||
// Create a bitset of universeSize bits.
|
||||
BitSet(Pool& pool, Uint32 universeSize) : universeSize(universeSize) {word = new(pool) Word[getSizeInWords(universeSize)]; clear();}
|
||||
|
||||
// Return the size of this bitset.
|
||||
Uint32 getSize() const {return universeSize;}
|
||||
|
||||
// Clear the bitset.
|
||||
void clear() {memset(word, 0x00, getSizeInWords(universeSize) << nBytesInWordLog2);}
|
||||
// Clear the bit at index.
|
||||
void clear(Uint32 index) {checkMember(index); word[getWordOffset(index)] &= ~getMask(index);}
|
||||
// Set the bitset.
|
||||
void set() {memset(word, 0xFF, getSizeInWords(universeSize) << nBytesInWordLog2);}
|
||||
// Set the bit at index.
|
||||
void set(Uint32 index) {checkMember(index); word[getWordOffset(index)] |= getMask(index);}
|
||||
// Return true if the bit at index is set.
|
||||
bool test(Uint32 index) const {checkMember(index); return (word[getWordOffset(index)] & getMask(index)) != 0;}
|
||||
// Union with the given bitset.
|
||||
inline void or(const BitSet& set);
|
||||
// Intersection with the given bitset.
|
||||
inline void and(const BitSet& set);
|
||||
// Difference with the given bitset.
|
||||
inline void difference(const BitSet& set);
|
||||
// Copy set.
|
||||
inline BitSet& operator = (const BitSet& set);
|
||||
// Return true if the bitset are identical.
|
||||
friend bool operator == (const BitSet& set1, const BitSet& set2);
|
||||
// Return true if the bitset are different.
|
||||
friend bool operator != (const BitSet& set1, const BitSet& set2);
|
||||
|
||||
// Logical operators.
|
||||
BitSet& operator |= (const BitSet& set) {or(set); return *this;}
|
||||
BitSet& operator &= (const BitSet& set) {and(set); return *this;}
|
||||
BitSet& operator -= (const BitSet& set) {difference(set); return *this;}
|
||||
|
||||
// Return the first bit at set to true or -1 if none.
|
||||
Int32 firstOne() const {return nextOne(-1);}
|
||||
// Return the next bit after index set to true or -1 if none.
|
||||
Int32 nextOne(Int32 pos) const;
|
||||
// Return the first bit at set to false or -1 if none.
|
||||
Int32 firstZero() const {return nextZero(-1);}
|
||||
// Return the next bit after index set to false or -1 if none.
|
||||
Int32 nextZero(Int32 pos) const;
|
||||
|
||||
// Iterator to conform with the set API.
|
||||
typedef Int32 iterator;
|
||||
// Return true if the walk is ordered.
|
||||
static bool isOrdered() {return true;}
|
||||
// Return the iterator for the first element of this set.
|
||||
iterator begin() const {return firstOne();}
|
||||
// Return the next iterator.
|
||||
iterator advance(iterator pos) const {return nextOne(pos);}
|
||||
// Return true if the iterator is at the end of the set.
|
||||
bool done(iterator pos) const {return pos == -1;}
|
||||
// Return the element corresponding to the given iterator.
|
||||
Uint32 get(iterator pos) const {return pos;}
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
// Print the set.
|
||||
void printPretty(LogModuleObject log);
|
||||
#endif // DEBUG_LOG
|
||||
};
|
||||
|
||||
// Union with the given bitset.
|
||||
//
|
||||
inline void BitSet::or(const BitSet& set)
|
||||
{
|
||||
checkUniverseCompatibility(set);
|
||||
Word* src = set.word;
|
||||
Word* dst = word;
|
||||
Word* limit = &src[getSizeInWords(universeSize)];
|
||||
|
||||
while (src < limit)
|
||||
*dst++ |= *src++;
|
||||
}
|
||||
|
||||
// Intersection with the given bitset.
|
||||
//
|
||||
inline void BitSet::and(const BitSet& set)
|
||||
{
|
||||
checkUniverseCompatibility(set);
|
||||
Word* src = set.word;
|
||||
Word* dst = word;
|
||||
Word* limit = &src[getSizeInWords(universeSize)];
|
||||
|
||||
while (src < limit)
|
||||
*dst++ &= *src++;
|
||||
}
|
||||
|
||||
// Difference with the given bitset.
|
||||
//
|
||||
inline void BitSet::difference(const BitSet& set)
|
||||
{
|
||||
checkUniverseCompatibility(set);
|
||||
Word* src = set.word;
|
||||
Word* dst = word;
|
||||
Word* limit = &src[getSizeInWords(universeSize)];
|
||||
|
||||
while (src < limit)
|
||||
*dst++ &= ~*src++;
|
||||
}
|
||||
|
||||
// Copy the given set into this set.
|
||||
//
|
||||
inline BitSet& BitSet::operator = (const BitSet& set)
|
||||
{
|
||||
checkUniverseCompatibility(set);
|
||||
if (this != &set)
|
||||
memcpy(word, set.word, getSizeInWords(universeSize) << nBytesInWordLog2);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Return true if the given set is identical to this set.
|
||||
inline bool operator == (const BitSet& set1, const BitSet& set2)
|
||||
{
|
||||
set1.checkUniverseCompatibility(set2);
|
||||
|
||||
if (&set1 == &set2)
|
||||
return true;
|
||||
|
||||
return memcmp(set1.word, set2.word, BitSet::getSizeInWords(set1.universeSize) << BitSet::nBytesInWordLog2) == 0;
|
||||
}
|
||||
|
||||
inline bool operator != (const BitSet& set1, const BitSet& set2) {return !(set1 == set2);}
|
||||
|
||||
#endif // _BITSET_H
|
||||
159
mozilla/ef/Compiler/RegisterAllocator/Coalescing.h
Normal file
159
mozilla/ef/Compiler/RegisterAllocator/Coalescing.h
Normal file
@@ -0,0 +1,159 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _COALESCING_H_
|
||||
#define _COALESCING_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "Pool.h"
|
||||
#include "RegisterPressure.h"
|
||||
#include "InterferenceGraph.h"
|
||||
#include "ControlGraph.h"
|
||||
#include "ControlNodes.h"
|
||||
#include "Instruction.h"
|
||||
#include "SparseSet.h"
|
||||
#include "RegisterAllocator.h"
|
||||
#include "RegisterAllocatorTools.h"
|
||||
|
||||
#if 1
|
||||
// Performing an ultra conservative coalescing meens that when we look at
|
||||
// candidates (source,destination) for coalescing we need to make sure
|
||||
// that the combined interference of the source and destination register
|
||||
// will not exceed the total number of register available for the register
|
||||
// class.
|
||||
#define ULTRA_CONSERVATIVE_COALESCING
|
||||
#else
|
||||
// If we are not doing an ultra conservative coalescing we have to make sure
|
||||
// that the total number of neighbor whose degree is greater than the total
|
||||
// number of register is not greater than the total number of register.
|
||||
#undef ULTRA_CONSERVATIVE_COALESCING
|
||||
#endif
|
||||
|
||||
template <class RegisterPressure>
|
||||
struct Coalescing
|
||||
{
|
||||
static bool coalesce(RegisterAllocator& registerAllocator);
|
||||
};
|
||||
|
||||
template <class RegisterPressure>
|
||||
bool Coalescing<RegisterPressure>::coalesce(RegisterAllocator& registerAllocator)
|
||||
{
|
||||
Pool& pool = registerAllocator.pool;
|
||||
|
||||
// Initialize the lookup table
|
||||
//
|
||||
Uint32 rangeCount = registerAllocator.rangeCount;
|
||||
RegisterName* newRange = new RegisterName[2 * rangeCount];
|
||||
RegisterName* coalescedRange = &newRange[rangeCount];
|
||||
RegisterName* name2range = registerAllocator.name2range;
|
||||
|
||||
init(coalescedRange, rangeCount);
|
||||
|
||||
SparseSet interferences(pool, rangeCount);
|
||||
InterferenceGraph<RegisterPressure>& iGraph = registerAllocator.iGraph;
|
||||
bool removedInstructions = false;
|
||||
|
||||
ControlGraph& controlGraph = registerAllocator.controlGraph;
|
||||
ControlNode** nodes = controlGraph.lndList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
|
||||
// Walk the nodes in the loop nesting depth list.
|
||||
for (Int32 n = nNodes - 1; n >= 0; n--) {
|
||||
InstructionList& instructions = nodes[n]->getInstructions();
|
||||
|
||||
InstructionList::iterator it = instructions.begin();
|
||||
while (!instructions.done(it)) {
|
||||
Instruction& instruction = instructions.get(it);
|
||||
it = instructions.advance(it);
|
||||
|
||||
if ((instruction.getFlags() & ifCopy) != 0) {
|
||||
assert(instruction.getInstructionUseBegin() != instruction.getInstructionUseEnd() && instruction.getInstructionUseBegin()[0].isRegister());
|
||||
assert(instruction.getInstructionDefineBegin() != instruction.getInstructionDefineEnd() && instruction.getInstructionDefineBegin()[0].isRegister());
|
||||
|
||||
RegisterName source = findRoot(name2range[instruction.getInstructionUseBegin()[0].getRegisterName()], coalescedRange);
|
||||
RegisterName destination = findRoot(name2range[instruction.getInstructionDefineBegin()[0].getRegisterName()], coalescedRange);
|
||||
|
||||
if (source == destination) {
|
||||
instruction.remove();
|
||||
} else if (!iGraph.interfere(source, destination)) {
|
||||
InterferenceVector* sourceVector = iGraph.getInterferenceVector(source);
|
||||
InterferenceVector* destinationVector = iGraph.getInterferenceVector(destination);
|
||||
|
||||
#ifdef ULTRA_CONSERVATIVE_COALESCING
|
||||
interferences.clear();
|
||||
|
||||
InterferenceVector* vector;
|
||||
for (vector = sourceVector; vector != NULL; vector = vector->next) {
|
||||
RegisterName* neighbors = vector->neighbors;
|
||||
for (Uint32 i = 0; i < vector->count; i++)
|
||||
interferences.set(findRoot(neighbors[i], coalescedRange));
|
||||
}
|
||||
for (vector = destinationVector; vector != NULL; vector = vector->next) {
|
||||
RegisterName* neighbors = vector->neighbors;
|
||||
for (Uint32 i = 0; i < vector->count; i++)
|
||||
interferences.set(findRoot(neighbors[i], coalescedRange));
|
||||
}
|
||||
|
||||
Uint32 count = interferences.getSize();
|
||||
#else // ULTRA_CONSERVATIVE_COALESCING
|
||||
trespass("not implemented");
|
||||
Uint32 count = 0;
|
||||
#endif // ULTRA_CONSERVATIVE_COALESCING
|
||||
|
||||
if (count < 6 /* FIX: should get the number from the class */) {
|
||||
// Update the interferences vector.
|
||||
if (sourceVector == NULL) {
|
||||
iGraph.setInterferenceVector(source, destinationVector);
|
||||
sourceVector = destinationVector;
|
||||
} else if (destinationVector == NULL)
|
||||
iGraph.setInterferenceVector(destination, sourceVector);
|
||||
else {
|
||||
InterferenceVector* last = NULL;
|
||||
for (InterferenceVector* v = sourceVector; v != NULL; v = v->next)
|
||||
last = v;
|
||||
assert(last);
|
||||
last->next = destinationVector;
|
||||
iGraph.setInterferenceVector(destination, sourceVector);
|
||||
}
|
||||
// Update the interference matrix.
|
||||
for (InterferenceVector* v = sourceVector; v != NULL; v = v->next) {
|
||||
RegisterName* neighbors = v->neighbors;
|
||||
for (Uint32 i = 0; i < v->count; i++) {
|
||||
RegisterName neighbor = findRoot(neighbors[i], coalescedRange);
|
||||
iGraph.setInterference(neighbor, source);
|
||||
iGraph.setInterference(neighbor, destination);
|
||||
}
|
||||
}
|
||||
|
||||
instruction.remove();
|
||||
coalescedRange[source] = destination;
|
||||
removedInstructions = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
registerAllocator.rangeCount = compress(registerAllocator.name2range, coalescedRange, registerAllocator.nameCount, rangeCount);
|
||||
delete newRange;
|
||||
|
||||
return removedInstructions;
|
||||
}
|
||||
|
||||
#endif // _COALESCING_H_
|
||||
283
mozilla/ef/Compiler/RegisterAllocator/Coloring.cpp
Normal file
283
mozilla/ef/Compiler/RegisterAllocator/Coloring.cpp
Normal file
@@ -0,0 +1,283 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef NEW_LAURENTM_CODE
|
||||
|
||||
#include "Coloring.h"
|
||||
#include "VirtualRegister.h"
|
||||
#include "FastBitSet.h"
|
||||
#include "FastBitMatrix.h"
|
||||
#include "CpuInfo.h"
|
||||
|
||||
bool Coloring::
|
||||
assignRegisters(FastBitMatrix& interferenceMatrix)
|
||||
{
|
||||
PRUint32 *stackPtr = new(pool) PRUint32[vRegManager.count()];
|
||||
|
||||
return select(interferenceMatrix, stackPtr, simplify(interferenceMatrix, stackPtr));
|
||||
}
|
||||
|
||||
PRInt32 Coloring::
|
||||
getLowestSpillCostRegister(FastBitSet& bitset)
|
||||
{
|
||||
PRInt32 lowest = bitset.firstOne();
|
||||
if (lowest != -1)
|
||||
{
|
||||
Flt32 cost = vRegManager.getVirtualRegister(lowest).spillInfo.spillCost;
|
||||
for (PRInt32 r = bitset.nextOne(lowest); r != -1; r = bitset.nextOne(r))
|
||||
{
|
||||
VirtualRegister& vReg = vRegManager.getVirtualRegister(r);
|
||||
if (!vReg.spillInfo.infiniteSpillCost && (vReg.spillInfo.spillCost < cost))
|
||||
{
|
||||
cost = vReg.spillInfo.spillCost;
|
||||
lowest = r;
|
||||
}
|
||||
}
|
||||
}
|
||||
return lowest;
|
||||
}
|
||||
|
||||
PRUint32* Coloring::
|
||||
simplify(FastBitMatrix interferenceMatrix, PRUint32* stackPtr)
|
||||
{
|
||||
// first we construct the sets low and high. low contains all nodes of degree
|
||||
// inferior to the number of register available on the processor. All the
|
||||
// nodes with an high degree and a finite spill cost are placed in high.
|
||||
// Nodes of high degree and infinite spill cost are not included in either sets.
|
||||
|
||||
PRUint32 nRegisters = vRegManager.count();
|
||||
FastBitSet low(pool, nRegisters);
|
||||
FastBitSet high(pool, nRegisters);
|
||||
FastBitSet stack(pool, nRegisters);
|
||||
|
||||
for (VirtualRegisterManager::iterator i = vRegManager.begin(); !vRegManager.done(i); i = vRegManager.advance(i))
|
||||
{
|
||||
VirtualRegister& vReg = vRegManager.getVirtualRegister(i);
|
||||
|
||||
if (vReg.getClass() == vrcStackSlot)
|
||||
{
|
||||
stack.set(i);
|
||||
vReg.colorRegister(nRegisters);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (vReg.colorInfo.interferenceDegree < NUMBER_OF_REGISTERS)
|
||||
low.set(i);
|
||||
else // if (!vReg.spillInfo.infiniteSpillCost)
|
||||
high.set(i);
|
||||
|
||||
// Set coloring info.
|
||||
vReg.spillInfo.willSpill = false;
|
||||
|
||||
switch(vReg.getClass())
|
||||
{
|
||||
case vrcInteger:
|
||||
vReg.colorRegister(LAST_GREGISTER + 1);
|
||||
break;
|
||||
case vrcFloatingPoint:
|
||||
case vrcFixedPoint:
|
||||
vReg.colorRegister(LAST_FPREGISTER + 1);
|
||||
break;
|
||||
default:
|
||||
PR_ASSERT(false); // Cannot happen.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// push the stack registers
|
||||
PRInt32 j;
|
||||
for (j = stack.firstOne(); j != -1; j = stack.nextOne(j))
|
||||
*stackPtr++ = j;
|
||||
|
||||
// simplify
|
||||
while (true)
|
||||
{
|
||||
PRInt32 r;
|
||||
while ((r = getLowestSpillCostRegister(low)) != -1)
|
||||
{
|
||||
VirtualRegister& vReg = vRegManager.getVirtualRegister(r);
|
||||
|
||||
/* update low and high */
|
||||
FastBitSet inter(interferenceMatrix.getRow(r), nRegisters);
|
||||
for (j = inter.firstOne(); j != -1; j = inter.nextOne(j))
|
||||
{
|
||||
VirtualRegister& neighbor = vRegManager.getVirtualRegister(j);
|
||||
// if the new interference degree of one of his neighbor becomes
|
||||
// NUMBER_OF_REGISTERS - 1 then it is added to the set 'low'.
|
||||
|
||||
PRUint32 maxInterference = 0;
|
||||
switch (neighbor.getClass())
|
||||
{
|
||||
case vrcInteger:
|
||||
maxInterference = NUMBER_OF_GREGISTERS;
|
||||
break;
|
||||
case vrcFloatingPoint:
|
||||
case vrcFixedPoint:
|
||||
maxInterference = NUMBER_OF_FPREGISTERS;
|
||||
break;
|
||||
default:
|
||||
PR_ASSERT(false);
|
||||
}
|
||||
if ((vRegManager.getVirtualRegister(j).colorInfo.interferenceDegree-- == maxInterference))
|
||||
{
|
||||
high.clear(j);
|
||||
low.set(j);
|
||||
}
|
||||
vReg.colorInfo.interferenceDegree--;
|
||||
interferenceMatrix.clear(r, j);
|
||||
interferenceMatrix.clear(j, r);
|
||||
}
|
||||
low.clear(r);
|
||||
|
||||
// Push this register.
|
||||
*stackPtr++ = r;
|
||||
}
|
||||
if ((r = getLowestSpillCostRegister(high)) != -1)
|
||||
{
|
||||
high.clear(r);
|
||||
low.set(r);
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
return stackPtr;
|
||||
}
|
||||
|
||||
bool Coloring::
|
||||
select(FastBitMatrix& interferenceMatrix, PRUint32* stackBase, PRUint32* stackPtr)
|
||||
{
|
||||
PRUint32 nRegisters = vRegManager.count();
|
||||
FastBitSet usedRegisters(NUMBER_OF_REGISTERS + 1); // usedRegisters if used for both GR & FPR.
|
||||
FastBitSet preColoredRegisters(NUMBER_OF_REGISTERS + 1);
|
||||
FastBitSet usedStack(nRegisters + 1);
|
||||
bool success = true;
|
||||
Int32 lastUsedSSR = -1;
|
||||
|
||||
// select
|
||||
while (stackPtr != stackBase)
|
||||
{
|
||||
// Pop one register.
|
||||
PRUint32 r = *--stackPtr;
|
||||
VirtualRegister& vReg = vRegManager.getVirtualRegister(r);
|
||||
|
||||
FastBitSet neighbors(interferenceMatrix.getRow(r), nRegisters);
|
||||
|
||||
if (vReg.getClass() == vrcStackSlot)
|
||||
// Stack slots coloring.
|
||||
{
|
||||
usedStack.clear();
|
||||
|
||||
for (PRInt32 i = neighbors.firstOne(); i != -1; i = neighbors.nextOne(i))
|
||||
usedStack.set(vRegManager.getVirtualRegister(i).getColor());
|
||||
|
||||
Int32 color = usedStack.firstZero();
|
||||
vReg.colorRegister(color);
|
||||
if (color > lastUsedSSR)
|
||||
lastUsedSSR = color;
|
||||
}
|
||||
else
|
||||
// Integer & Floating point register coloring.
|
||||
{
|
||||
usedRegisters.clear();
|
||||
preColoredRegisters.clear();
|
||||
|
||||
for (PRInt32 i = neighbors.firstOne(); i != -1; i = neighbors.nextOne(i))
|
||||
{
|
||||
VirtualRegister& nvReg = vRegManager.getVirtualRegister(i);
|
||||
usedRegisters.set(nvReg.getColor());
|
||||
if (nvReg.isPreColored())
|
||||
preColoredRegisters.set(nvReg.getPreColor());
|
||||
}
|
||||
if (vReg.hasSpecialInterference)
|
||||
usedRegisters |= vReg.specialInterference;
|
||||
|
||||
PRInt8 c = -1;
|
||||
PRInt8 maxColor = 0;
|
||||
PRInt8 firstColor = 0;
|
||||
switch (vReg.getClass())
|
||||
{
|
||||
case vrcInteger:
|
||||
firstColor = FIRST_GREGISTER;
|
||||
maxColor = LAST_GREGISTER;
|
||||
break;
|
||||
case vrcFloatingPoint:
|
||||
case vrcFixedPoint:
|
||||
firstColor = FIRST_FPREGISTER;
|
||||
maxColor = LAST_FPREGISTER;
|
||||
break;
|
||||
default:
|
||||
PR_ASSERT(false);
|
||||
}
|
||||
|
||||
if (vReg.isPreColored())
|
||||
{
|
||||
c = vReg.getPreColor();
|
||||
if (usedRegisters.test(c))
|
||||
c = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (c = usedRegisters.nextZero(firstColor - 1); (c >= 0) && (c <= maxColor) && (preColoredRegisters.test(c));
|
||||
c = usedRegisters.nextZero(c)) {}
|
||||
}
|
||||
|
||||
if ((c >= 0) && (c <= maxColor))
|
||||
{
|
||||
vReg.colorRegister(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
VirtualRegister& stackRegister = vRegManager.newVirtualRegister(vrcStackSlot);
|
||||
vReg.equivalentRegister[vrcStackSlot] = &stackRegister;
|
||||
vReg.spillInfo.willSpill = true;
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
if (success)
|
||||
{
|
||||
for (VirtualRegisterManager::iterator i = vRegManager.begin(); !vRegManager.done(i); i = vRegManager.advance(i))
|
||||
{
|
||||
VirtualRegister& vReg = vRegManager.getVirtualRegister(i);
|
||||
switch (vReg.getClass())
|
||||
{
|
||||
case vrcInteger:
|
||||
if (vReg.getColor() > LAST_GREGISTER)
|
||||
PR_ASSERT(false);
|
||||
break;
|
||||
case vrcFloatingPoint:
|
||||
case vrcFixedPoint:
|
||||
#if NUMBER_OF_FPREGISTERS != 0
|
||||
if (vReg.getColor() > LAST_FPREGISTER)
|
||||
PR_ASSERT(false);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
vRegManager.nUsedStackSlots = lastUsedSSR + 1;
|
||||
return success;
|
||||
}
|
||||
#endif // NEW_LAURENTM_CODE
|
||||
284
mozilla/ef/Compiler/RegisterAllocator/Coloring.h
Normal file
284
mozilla/ef/Compiler/RegisterAllocator/Coloring.h
Normal file
@@ -0,0 +1,284 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "ControlGraph.h"
|
||||
#include "ControlNodes.h"
|
||||
#include "Instruction.h"
|
||||
#include "RegisterAllocator.h"
|
||||
#include "VirtualRegister.h"
|
||||
#include "InterferenceGraph.h"
|
||||
#include "SparseSet.h"
|
||||
#include "Spilling.h"
|
||||
#include "Splits.h"
|
||||
|
||||
UT_EXTERN_LOG_MODULE(RegAlloc);
|
||||
|
||||
template <class RegisterPressure>
|
||||
class Coloring
|
||||
{
|
||||
private:
|
||||
static RegisterName* simplify(RegisterAllocator& registerAllocator, RegisterName* coloringStack);
|
||||
static bool select(RegisterAllocator& registerAllocator, RegisterName* coloringStack, RegisterName* coloringStackPtr);
|
||||
|
||||
public:
|
||||
static bool color(RegisterAllocator& registerAllocator);
|
||||
static void finalColoring(RegisterAllocator& registerAllocator);
|
||||
};
|
||||
|
||||
|
||||
template <class RegisterPressure>
|
||||
void Coloring<RegisterPressure>::finalColoring(RegisterAllocator& registerAllocator)
|
||||
{
|
||||
RegisterName* color = registerAllocator.color;
|
||||
RegisterName* name2range = registerAllocator.name2range;
|
||||
|
||||
ControlGraph& controlGraph = registerAllocator.controlGraph;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
InstructionList& instructions = nodes[n]->getInstructions();
|
||||
|
||||
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister()) {
|
||||
usePtr->setRegisterName(color[name2range[usePtr->getRegisterName()]]);
|
||||
#ifdef DEBUG
|
||||
RegisterID rid = usePtr->getRegisterID();
|
||||
setColoredRegister(rid);
|
||||
usePtr->setRegisterID(rid);
|
||||
#endif // DEBUG
|
||||
}
|
||||
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister()) {
|
||||
definePtr->setRegisterName(color[name2range[definePtr->getRegisterName()]]);
|
||||
#ifdef DEBUG
|
||||
RegisterID rid = definePtr->getRegisterID();
|
||||
setColoredRegister(rid);
|
||||
definePtr->setRegisterID(rid);
|
||||
#endif // DEBUG
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
bool Coloring<RegisterPressure>::select(RegisterAllocator& registerAllocator, RegisterName* coloringStack, RegisterName* coloringStackPtr)
|
||||
{
|
||||
Uint32 rangeCount = registerAllocator.rangeCount;
|
||||
RegisterName* color = new RegisterName[rangeCount];
|
||||
registerAllocator.color = color;
|
||||
|
||||
for (Uint32 r = 1; r < rangeCount; r++)
|
||||
color[r] = RegisterName(6); // FIX;
|
||||
|
||||
// Color the preColored registers.
|
||||
//
|
||||
VirtualRegisterManager& vrManager = registerAllocator.vrManager;
|
||||
RegisterName* name2range = registerAllocator.name2range;
|
||||
PreColoredRegister* machineEnd = vrManager.getMachineRegistersEnd();
|
||||
for (PreColoredRegister* machinePtr = vrManager.getMachineRegistersBegin(); machinePtr < machineEnd; machinePtr++)
|
||||
if (machinePtr->id != invalidID) {
|
||||
color[name2range[getName(machinePtr->id)]] = machinePtr->color;
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\twill preColor range %d as %d\n", name2range[getName(machinePtr->id)], machinePtr->color));
|
||||
}
|
||||
|
||||
SpillCost* cost = registerAllocator.spillCost;
|
||||
Pool& pool = registerAllocator.pool;
|
||||
SparseSet& spill = *new(pool) SparseSet(pool, rangeCount);
|
||||
registerAllocator.willSpill = &spill;
|
||||
SparseSet neighborColors(pool, 6); // FIX
|
||||
InterferenceGraph<RegisterPressure>& iGraph = registerAllocator.iGraph;
|
||||
|
||||
bool coloringFailed = false;
|
||||
while (coloringStackPtr > coloringStack) {
|
||||
RegisterName range = *--coloringStackPtr;
|
||||
|
||||
if (!cost[range].infinite && cost[range].cost < 0) {
|
||||
coloringFailed = true;
|
||||
spill.set(range);
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\tfailed to color %d, will spill.\n", range));
|
||||
} else {
|
||||
neighborColors.clear();
|
||||
|
||||
for (InterferenceVector* vector = iGraph.getInterferenceVector(range); vector != NULL; vector = vector->next)
|
||||
for (Int32 i = vector->count - 1; i >= 0; --i) {
|
||||
RegisterName neighborColor = color[vector->neighbors[i]];
|
||||
if (neighborColor < 6) // FIX
|
||||
neighborColors.set(neighborColor);
|
||||
}
|
||||
|
||||
if (neighborColors.getSize() == 6) { // FIX
|
||||
coloringFailed = true;
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\tfailed to color %d, ", range));
|
||||
|
||||
if (!Splits<RegisterPressure>::findSplit(registerAllocator, color, range)) {
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("will spill.\n"));
|
||||
spill.set(range);
|
||||
} else
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("will split.\n"));
|
||||
} else {
|
||||
for (Uint32 i = 0; i < 6; i++) // FIX
|
||||
if (!neighborColors.test(i)) {
|
||||
fprintf(stdout, "\twill color %d as %d\n", range, i);
|
||||
color[range] = RegisterName(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
if (coloringFailed) {
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("Coloring failed:\n"));
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\twill spill: "));
|
||||
spill.printPretty(UT_LOG_MODULE(RegAlloc));
|
||||
} else {
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("Coloring succeeded:\n"));
|
||||
for (Uint32 i = 1; i < rangeCount; i++)
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\trange %d colored as %d\n", i, color[i]));
|
||||
}
|
||||
#endif
|
||||
|
||||
return !coloringFailed;
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
RegisterName* Coloring<RegisterPressure>::simplify(RegisterAllocator& registerAllocator, RegisterName* coloringStack)
|
||||
{
|
||||
InterferenceGraph<RegisterPressure>& iGraph = registerAllocator.iGraph;
|
||||
SpillCost* spillCost = registerAllocator.spillCost;
|
||||
Uint32 rangeCount = registerAllocator.rangeCount;
|
||||
|
||||
Uint32* degree = new Uint32[rangeCount];
|
||||
for (RegisterName i = RegisterName(1); i < rangeCount; i = RegisterName(i + 1)) {
|
||||
InterferenceVector* vector = iGraph.getInterferenceVector(i);
|
||||
degree[i] = (vector != NULL) ? vector->count : 0;
|
||||
}
|
||||
|
||||
Pool& pool = registerAllocator.pool;
|
||||
SparseSet low(pool, rangeCount);
|
||||
SparseSet high(pool, rangeCount);
|
||||
SparseSet highInfinite(pool, rangeCount);
|
||||
SparseSet preColored(pool, rangeCount);
|
||||
|
||||
// Get the precolored registers.
|
||||
//
|
||||
VirtualRegisterManager& vrManager = registerAllocator.vrManager;
|
||||
RegisterName* name2range = registerAllocator.name2range;
|
||||
PreColoredRegister* machineEnd = vrManager.getMachineRegistersEnd();
|
||||
for (PreColoredRegister* machinePtr = vrManager.getMachineRegistersBegin(); machinePtr < machineEnd; machinePtr++)
|
||||
if (machinePtr->id != invalidID)
|
||||
preColored.set(name2range[getName(machinePtr->id)]);
|
||||
|
||||
// Insert the live ranges in the sets.
|
||||
//
|
||||
for (Uint32 range = 1; range < rangeCount; range++)
|
||||
if (!preColored.test(range))
|
||||
if (degree[range] < 6) // FIX
|
||||
low.set(range);
|
||||
else if (!spillCost[range].infinite)
|
||||
high.set(range);
|
||||
else
|
||||
highInfinite.set(range);
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("Coloring sets:\n\tlow = "));
|
||||
low.printPretty(UT_LOG_MODULE(RegAlloc));
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\thigh = "));
|
||||
high.printPretty(UT_LOG_MODULE(RegAlloc));
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\thighInfinite = "));
|
||||
highInfinite.printPretty(UT_LOG_MODULE(RegAlloc));
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\tpreColored = "));
|
||||
preColored.printPretty(UT_LOG_MODULE(RegAlloc));
|
||||
#endif // DEBUG_LOG
|
||||
|
||||
RegisterName* coloringStackPtr = coloringStack;
|
||||
|
||||
while (low.getSize() != 0 || high.getSize() != 0) {
|
||||
while (low.getSize() != 0) {
|
||||
RegisterName range = RegisterName(low.getOne());
|
||||
low.clear(range);
|
||||
*coloringStackPtr++ = range;
|
||||
|
||||
for (InterferenceVector* vector = iGraph.getInterferenceVector(range); vector != NULL; vector = vector->next)
|
||||
for (Int32 i = (vector->count - 1); i >= 0; --i) {
|
||||
RegisterName neighbor = vector->neighbors[i];
|
||||
degree[neighbor]--;
|
||||
|
||||
if (degree[neighbor] < 6) // FIX
|
||||
if (high.test(neighbor)) {
|
||||
high.clear(neighbor);
|
||||
low.set(neighbor);
|
||||
} else if (highInfinite.test(neighbor)) {
|
||||
highInfinite.clear(neighbor);
|
||||
low.set(neighbor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (high.getSize() != 0) {
|
||||
RegisterName best = RegisterName(high.getOne());
|
||||
double bestCost = spillCost[best].cost;
|
||||
double bestDegree = degree[best];
|
||||
|
||||
// Choose the next best candidate.
|
||||
//
|
||||
for (SparseSet::iterator i = high.begin(); !high.done(i); i = high.advance(i)) {
|
||||
RegisterName range = RegisterName(high.get(i));
|
||||
double thisCost = spillCost[range].cost;
|
||||
double thisDegree = degree[range];
|
||||
|
||||
if (thisCost * bestDegree < bestCost * thisDegree) {
|
||||
best = range;
|
||||
bestCost = thisCost;
|
||||
bestDegree = thisDegree;
|
||||
}
|
||||
}
|
||||
|
||||
high.clear(best);
|
||||
low.set(best);
|
||||
}
|
||||
}
|
||||
assert(highInfinite.getSize() == 0);
|
||||
|
||||
delete degree;
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("Coloring stack:\n\t"));
|
||||
for (RegisterName* sp = coloringStack; sp < coloringStackPtr; ++sp)
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("%d ", *sp));
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\n"));
|
||||
#endif // DEBUG_LOG
|
||||
|
||||
return coloringStackPtr;
|
||||
}
|
||||
|
||||
|
||||
template <class RegisterPressure>
|
||||
bool Coloring<RegisterPressure>::color(RegisterAllocator& registerAllocator)
|
||||
{
|
||||
RegisterName* coloringStack = new RegisterName[registerAllocator.rangeCount];
|
||||
return select(registerAllocator, coloringStack, simplify(registerAllocator, coloringStack));
|
||||
}
|
||||
212
mozilla/ef/Compiler/RegisterAllocator/DominatorGraph.cpp
Normal file
212
mozilla/ef/Compiler/RegisterAllocator/DominatorGraph.cpp
Normal file
@@ -0,0 +1,212 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include <string.h>
|
||||
#include "ControlGraph.h"
|
||||
#include "ControlNodes.h"
|
||||
|
||||
#include "DominatorGraph.h"
|
||||
|
||||
DominatorGraph::DominatorGraph(ControlGraph& controlGraph) : controlGraph(controlGraph)
|
||||
{
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
GtoV = new Uint32[nNodes + 1];
|
||||
VtoG = new Uint32[nNodes + 1];
|
||||
|
||||
Uint32 v = 1;
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
VtoG[v] = n;
|
||||
GtoV[n] = v++;
|
||||
}
|
||||
|
||||
// Initialize all the 1-based arrays.
|
||||
//
|
||||
parent = new Uint32[v];
|
||||
semi = new Uint32[v];
|
||||
vertex = new Uint32[v];
|
||||
label = new Uint32[v];
|
||||
size = new Uint32[v];
|
||||
ancestor = new Uint32[v];
|
||||
child = new Uint32[v];
|
||||
dom = new Uint32[v];
|
||||
bucket = new DGLinkedList*[v];
|
||||
|
||||
memset(semi, '\0', v * sizeof(Uint32));
|
||||
memset(bucket, '\0', v * sizeof(DGLinkedList*));
|
||||
|
||||
vCount = v;
|
||||
|
||||
build();
|
||||
|
||||
delete parent;
|
||||
delete semi;
|
||||
delete vertex;
|
||||
delete label;
|
||||
delete size;
|
||||
delete ancestor;
|
||||
delete child;
|
||||
delete dom;
|
||||
delete bucket;
|
||||
}
|
||||
|
||||
Uint32 DominatorGraph::DFS(Uint32 vx, Uint32 n)
|
||||
{
|
||||
semi[vx] = ++n;
|
||||
vertex[n] = label[vx] = vx;
|
||||
ancestor[vx] = child[vx] = 0;
|
||||
size[vx] = 1;
|
||||
|
||||
|
||||
ControlNode& node = *controlGraph.dfsList[VtoG[vx]];
|
||||
ControlEdge* successorEnd = node.getSuccessorsEnd();
|
||||
for (ControlEdge* successorPtr = node.getSuccessorsBegin(); successorPtr < successorEnd; successorPtr++) {
|
||||
Uint32 w = GtoV[successorPtr->getTarget().dfsNum];
|
||||
if (semi[w] == 0) {
|
||||
parent[w] = vx;
|
||||
n = DFS(w, n);
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
void DominatorGraph::LINK(Uint32 vx, Uint32 w)
|
||||
{
|
||||
Uint32 s = w;
|
||||
|
||||
while (semi[label[w]] < semi[label[child[s]]]) {
|
||||
if (size[s] + size[child[child[s]]] >= (size[child[s]] << 1)) {
|
||||
ancestor[child[s]] = s;
|
||||
child[s] = child[child[s]];
|
||||
} else {
|
||||
size[child[s]] = size[s];
|
||||
s = ancestor[s] = child[s];
|
||||
}
|
||||
}
|
||||
label[s] = label[w];
|
||||
size[vx] += size[w];
|
||||
if(size[vx] < (size[w] << 1)) {
|
||||
Uint32 t = s;
|
||||
s = child[vx];
|
||||
child[vx] = t;
|
||||
}
|
||||
while( s != 0 ) {
|
||||
ancestor[s] = vx;
|
||||
s = child[s];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DominatorGraph::COMPRESS(Uint32 vx)
|
||||
{
|
||||
if(ancestor[ancestor[vx]] != 0) {
|
||||
COMPRESS(ancestor[vx]);
|
||||
if(semi[label[ancestor[vx]]] < semi[label[vx]])
|
||||
label[vx] = label[ancestor[vx]];
|
||||
ancestor[vx] = ancestor[ancestor[vx]];
|
||||
}
|
||||
}
|
||||
|
||||
Uint32 DominatorGraph::EVAL(Uint32 vx)
|
||||
{
|
||||
if(ancestor[vx] == 0)
|
||||
return label[vx];
|
||||
COMPRESS(vx);
|
||||
return (semi[label[ancestor[vx]]] >= semi[label[vx]]) ? label[vx] : label[ancestor[vx]];
|
||||
}
|
||||
|
||||
void DominatorGraph::build()
|
||||
{
|
||||
Uint32 n = DFS(GtoV[0], 0);
|
||||
size[0] = label[0] = semi[0];
|
||||
|
||||
for (Uint32 i = n; i >= 2; i--) {
|
||||
Uint32 w = vertex[i];
|
||||
|
||||
ControlNode& node = *controlGraph.dfsList[VtoG[w]];
|
||||
const DoublyLinkedList<ControlEdge>& predecessors = node.getPredecessors();
|
||||
for (DoublyLinkedList<ControlEdge>::iterator p = predecessors.begin(); !predecessors.done(p); p = predecessors.advance(p)) {
|
||||
Uint32 vx = GtoV[predecessors.get(p).getSource().dfsNum];
|
||||
Uint32 u = EVAL(vx);
|
||||
|
||||
if(semi[u] < semi[w])
|
||||
semi[w] = semi[u];
|
||||
}
|
||||
|
||||
DGLinkedList* elem = new DGLinkedList();
|
||||
elem->next = bucket[vertex[semi[w]]];
|
||||
elem->index = w;
|
||||
bucket[vertex[semi[w]]] = elem;
|
||||
|
||||
LINK(parent[w], w);
|
||||
|
||||
elem = bucket[parent[w]];
|
||||
while(elem != NULL) {
|
||||
Uint32 vx = elem->index;
|
||||
Uint32 u = EVAL(vx);
|
||||
dom[vx] = (semi[u] < semi[vx]) ? u : parent[w];
|
||||
elem = elem->next;
|
||||
}
|
||||
}
|
||||
|
||||
memset(size, '\0', n * sizeof(Uint32));
|
||||
Pool& pool = controlGraph.pool;
|
||||
nodes = new(pool) DGNode[n];
|
||||
|
||||
for(Uint32 j = 2; j <= n; j++) {
|
||||
Uint32 w = vertex[j];
|
||||
Uint32 d = dom[w];
|
||||
if(d != vertex[semi[w]]) {
|
||||
d = dom[d];
|
||||
dom[w] = d;
|
||||
}
|
||||
size[d]++;
|
||||
}
|
||||
dom[GtoV[0]] = 0;
|
||||
|
||||
for (Uint32 k = 1; k <= n; k++) {
|
||||
DGNode& node = nodes[VtoG[k]];
|
||||
Uint32 count = size[k];
|
||||
node.successorsEnd = node.successorsBegin = (count) ? new(pool) Uint32[count] : (Uint32*) 0;
|
||||
}
|
||||
|
||||
for (Uint32 l = 2; l <= n; l++)
|
||||
*(nodes[VtoG[dom[l]]].successorsEnd)++ = VtoG[l];
|
||||
}
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
void DominatorGraph::printPretty(LogModuleObject log)
|
||||
{
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Dominator Graph:\n"));
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
for (Uint32 i = 0; i < nNodes; i++) {
|
||||
DGNode& node = nodes[i];
|
||||
if (node.successorsBegin != node.successorsEnd) {
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\tN%d dominates ", i));
|
||||
for (Uint32* successorsPtr = node.successorsBegin; successorsPtr < node.successorsEnd; successorsPtr++)
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("N%d ", *successorsPtr));
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\n"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // DEBUG_LOG
|
||||
|
||||
|
||||
|
||||
80
mozilla/ef/Compiler/RegisterAllocator/DominatorGraph.h
Normal file
80
mozilla/ef/Compiler/RegisterAllocator/DominatorGraph.h
Normal file
@@ -0,0 +1,80 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _DOMINATOR_GRAPH_H_
|
||||
#define _DOMINATOR_GRAPH_H_
|
||||
|
||||
#include "LogModule.h"
|
||||
|
||||
class ControlGraph;
|
||||
|
||||
struct DGNode
|
||||
{
|
||||
Uint32* successorsBegin;
|
||||
Uint32* successorsEnd;
|
||||
};
|
||||
|
||||
struct DGLinkedList
|
||||
{
|
||||
DGLinkedList* next;
|
||||
Uint32 index;
|
||||
};
|
||||
|
||||
class DominatorGraph
|
||||
{
|
||||
private:
|
||||
|
||||
ControlGraph& controlGraph;
|
||||
|
||||
Uint32 vCount;
|
||||
|
||||
Uint32* VtoG;
|
||||
Uint32* GtoV;
|
||||
Uint32* parent;
|
||||
Uint32* semi;
|
||||
Uint32* vertex;
|
||||
Uint32* label;
|
||||
Uint32* size;
|
||||
Uint32* ancestor;
|
||||
Uint32* child;
|
||||
Uint32* dom;
|
||||
DGLinkedList** bucket;
|
||||
DGNode* nodes;
|
||||
|
||||
private:
|
||||
|
||||
void build();
|
||||
|
||||
Uint32 DFS(Uint32 vx, Uint32 n);
|
||||
void LINK(Uint32 vx, Uint32 w);
|
||||
void COMPRESS(Uint32 vx);
|
||||
Uint32 EVAL(Uint32 vx);
|
||||
|
||||
public:
|
||||
|
||||
DominatorGraph(ControlGraph& controlGraph);
|
||||
|
||||
Uint32* getSuccessorsBegin(Uint32 n) const {return nodes[n].successorsBegin;}
|
||||
Uint32* getSuccessorsEnd(Uint32 n) const {return nodes[n].successorsEnd;}
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
void printPretty(LogModuleObject log);
|
||||
#endif // DEBUG_LOG
|
||||
};
|
||||
|
||||
#endif // _DOMINATOR_GRAPH_H_
|
||||
20
mozilla/ef/Compiler/RegisterAllocator/HashSet.cpp
Normal file
20
mozilla/ef/Compiler/RegisterAllocator/HashSet.cpp
Normal file
@@ -0,0 +1,20 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "HashSet.h"
|
||||
97
mozilla/ef/Compiler/RegisterAllocator/HashSet.h
Normal file
97
mozilla/ef/Compiler/RegisterAllocator/HashSet.h
Normal file
@@ -0,0 +1,97 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _HASH_SET_H_
|
||||
#define _HASH_SET_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "Pool.h"
|
||||
#include <string.h>
|
||||
|
||||
struct HashSetElement
|
||||
{
|
||||
Uint32 index;
|
||||
HashSetElement* next;
|
||||
};
|
||||
|
||||
class HashSet
|
||||
{
|
||||
private:
|
||||
|
||||
static const hashSize = 64;
|
||||
|
||||
// Return the hash code for the given element index.
|
||||
static Uint32 getHashCode(Uint32 index) {return index & (hashSize - 1);} // Could be better !
|
||||
|
||||
private:
|
||||
|
||||
Pool& allocationPool;
|
||||
HashSetElement** bucket;
|
||||
HashSetElement* free;
|
||||
|
||||
private:
|
||||
|
||||
// No copy constructor.
|
||||
HashSet(const HashSet&);
|
||||
// No copy operator.
|
||||
void operator = (const HashSet&);
|
||||
|
||||
public:
|
||||
|
||||
// Create a new HashSet.
|
||||
inline HashSet(Pool& pool, Uint32 universeSize);
|
||||
|
||||
// Clear the hashset.
|
||||
void clear();
|
||||
// Clear the element for the given index.
|
||||
void clear(Uint32 index);
|
||||
// Set the element for the given index.
|
||||
void set(Uint32 index);
|
||||
// Return true if the element at index is a member.
|
||||
bool test(Uint32 index) const;
|
||||
// Union with the given hashset.
|
||||
inline void or(const HashSet& set);
|
||||
// Intersection with the given hashset.
|
||||
inline void and(const HashSet& set);
|
||||
// Difference with the given hashset.
|
||||
inline void difference(const HashSet& set);
|
||||
|
||||
// Logical operators.
|
||||
HashSet& operator |= (const HashSet& set) {or(set); return *this;}
|
||||
HashSet& operator &= (const HashSet& set) {and(set); return *this;}
|
||||
HashSet& operator -= (const HashSet& set) {difference(set); return *this;}
|
||||
|
||||
// Iterator to conform with the set API.
|
||||
typedef HashSetElement* iterator;
|
||||
// Return the iterator for the first element of this set.
|
||||
iterator begin() const;
|
||||
// Return the next iterator.
|
||||
iterator advance(iterator pos) const;
|
||||
// Return true if the iterator is at the end of the set.
|
||||
bool done(iterator pos) const {return pos == NULL;}
|
||||
};
|
||||
|
||||
|
||||
inline HashSet::HashSet(Pool& pool, Uint32 /*universeSize*/)
|
||||
: allocationPool(pool), free(NULL)
|
||||
{
|
||||
bucket = new(pool) HashSetElement*[hashSize];
|
||||
memset(bucket, '\0', sizeof(HashSetElement*));
|
||||
}
|
||||
|
||||
#endif // _HASH_SET_H_
|
||||
213
mozilla/ef/Compiler/RegisterAllocator/IndexedPool.h
Normal file
213
mozilla/ef/Compiler/RegisterAllocator/IndexedPool.h
Normal file
@@ -0,0 +1,213 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _INDEXED_POOL_H_
|
||||
#define _INDEXED_POOL_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// IndexedPool<IndexedObjectSubclass> is an indexed pool of objects. The
|
||||
// template parameter 'IndexedObjectSubclass' must be a subclass of the struct
|
||||
// IndexedObject.
|
||||
//
|
||||
// When the indexed pool is ask to allocate and initialize a new object (using
|
||||
// the operator new(anIndexedPool) it will zero the memory used to store the
|
||||
// object and initialize the field 'index' of this object to its position in
|
||||
// the pool.
|
||||
//
|
||||
// An object allocated by the indexed pool can be freed by calling the method
|
||||
// IndexedPool::release(IndexedElement& objectIndex).
|
||||
//
|
||||
// example:
|
||||
//
|
||||
// IndexedPool<IndexedElement> elementPool;
|
||||
//
|
||||
// IndexedElement& element1 = *new(elementPool) IndexedElement();
|
||||
// IndexedElement& element2 = *new(elementPool) IndexedElement();
|
||||
//
|
||||
// indexedPool.release(element1);
|
||||
// IndexedElement& element3 = *new(elementPool) IndexedElement();
|
||||
//
|
||||
// At this point element1 is no longer a valid object, element2 is at
|
||||
// index 2 and element3 is at index 1.
|
||||
//
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// IndexedObject -
|
||||
//
|
||||
|
||||
template<class Object>
|
||||
struct IndexedObject
|
||||
{
|
||||
Uint32 index; // Index in the pool.
|
||||
Object* next; // Used to link IndexedObject together.
|
||||
|
||||
Uint32 getIndex() {return index;}
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// IndexedPool<IndexedObject> -
|
||||
//
|
||||
|
||||
template <class IndexedObject>
|
||||
class IndexedPool
|
||||
{
|
||||
private:
|
||||
|
||||
static const blockSize = 4; // Size of one block.
|
||||
|
||||
Uint32 nBlocks; // Number of blocks in the pool.
|
||||
IndexedObject** block; // Array of block pointers.
|
||||
IndexedObject* freeObjects; // Chained list of free IndexedObjects.
|
||||
Uint32 nextIndex; // Index of the next free object in the last block.
|
||||
|
||||
private:
|
||||
|
||||
void allocateAnotherBlock();
|
||||
IndexedObject& newObject();
|
||||
|
||||
public:
|
||||
|
||||
IndexedPool() : nBlocks(0), block(NULL), freeObjects(NULL), nextIndex(1) {}
|
||||
~IndexedPool();
|
||||
|
||||
IndexedObject& get(Uint32 index) const;
|
||||
void release(IndexedObject& object);
|
||||
|
||||
void setSize(Uint32 size) {assert(size < nextIndex); nextIndex = size;}
|
||||
|
||||
// Return the universe size.
|
||||
Uint32 getSize() {return nextIndex;}
|
||||
|
||||
friend void* operator new(size_t, IndexedPool<IndexedObject>& pool); // Needs to call newObject().
|
||||
};
|
||||
|
||||
// Free all the memory allocated for this object.
|
||||
//
|
||||
template <class IndexedObject>
|
||||
IndexedPool<IndexedObject>::~IndexedPool()
|
||||
{
|
||||
for (Uint32 n = 0; n < nBlocks; n++)
|
||||
free(&((IndexedObject **) &block[n][n*blockSize])[-(n + 1)]);
|
||||
}
|
||||
|
||||
// Release the given. This object will be iserted in the chained
|
||||
// list of free IndexedObjects. To minimize the fragmentation the chained list
|
||||
// is ordered by ascending indexes.
|
||||
//
|
||||
template <class IndexedObject>
|
||||
void IndexedPool<IndexedObject>::release(IndexedObject& object)
|
||||
{
|
||||
Uint32 index = object.index;
|
||||
IndexedObject* list = freeObjects;
|
||||
|
||||
assert(&object == &get(index)); // Make sure that object is owned by this pool.
|
||||
|
||||
if (list == NULL) { // The list is empty.
|
||||
freeObjects = &object;
|
||||
object.next = NULL;
|
||||
} else { // The list contains at least 1 element.
|
||||
if (index < list->index) { // insert as first element.
|
||||
freeObjects = &object;
|
||||
object.next = list;
|
||||
} else { // Find this object's place.
|
||||
while ((list->next) != NULL && (list->next->index < index))
|
||||
list = list->next;
|
||||
|
||||
object.next = list->next;
|
||||
list->next = &object;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
// Sanity check to be sure that the list is correctly ordered.
|
||||
for (IndexedObject* obj = freeObjects; obj != NULL; obj = obj->next)
|
||||
if (obj->next != NULL)
|
||||
assert(obj->index < obj->next->index);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Create a new block of IndexedObjects. We will allocate the memory to
|
||||
// store IndexedPool::blockSize IndexedObject and the new Array of block
|
||||
// pointers.
|
||||
// The newly created IndexedObjects will not be initialized.
|
||||
//
|
||||
template <class IndexedObject>
|
||||
void IndexedPool<IndexedObject>::allocateAnotherBlock()
|
||||
{
|
||||
void* memory = (void *) malloc((nBlocks + 1) * sizeof(Uint32) + blockSize * sizeof(IndexedObject));
|
||||
|
||||
memcpy(memory, block, nBlocks * sizeof(Uint32));
|
||||
|
||||
block = (IndexedObject **) memory;
|
||||
IndexedObject* objects = (IndexedObject *) &block[nBlocks + 1];
|
||||
|
||||
block[nBlocks] = &objects[-(nBlocks * blockSize)];
|
||||
nBlocks++;
|
||||
}
|
||||
|
||||
// Return the IndexedObject at the position 'index' in the pool.
|
||||
//
|
||||
template <class IndexedObject>
|
||||
IndexedObject& IndexedPool<IndexedObject>::get(Uint32 index) const
|
||||
{
|
||||
Uint32 blockIndex = index / blockSize;
|
||||
assert(blockIndex < nBlocks);
|
||||
|
||||
return block[blockIndex][index];
|
||||
}
|
||||
|
||||
// Return the reference of an unused object in the pool.
|
||||
//
|
||||
template <class IndexedObject>
|
||||
IndexedObject& IndexedPool<IndexedObject>::newObject()
|
||||
{
|
||||
if (freeObjects != NULL) {
|
||||
IndexedObject& newObject = *freeObjects;
|
||||
freeObjects = newObject.next;
|
||||
return newObject;
|
||||
}
|
||||
|
||||
Uint32 nextIndex = this->nextIndex++;
|
||||
Uint32 blockIndex = nextIndex / blockSize;
|
||||
|
||||
while (blockIndex >= nBlocks)
|
||||
allocateAnotherBlock();
|
||||
|
||||
IndexedObject& newObject = block[blockIndex][nextIndex];
|
||||
newObject.index = nextIndex;
|
||||
|
||||
return newObject;
|
||||
}
|
||||
|
||||
// Return the address of the next unsused object in the given
|
||||
// indexed pool. The field index of the newly allocated object
|
||||
// will be initialized to the corresponding index of this object
|
||||
// in the pool.
|
||||
//
|
||||
template <class IndexedObject>
|
||||
void* operator new(size_t size, IndexedPool<IndexedObject>& pool)
|
||||
{
|
||||
assert(size == sizeof(IndexedObject));
|
||||
return (void *) &pool.newObject();
|
||||
}
|
||||
|
||||
#endif // _INDEXED_POOL_H_
|
||||
258
mozilla/ef/Compiler/RegisterAllocator/InterferenceGraph.h
Normal file
258
mozilla/ef/Compiler/RegisterAllocator/InterferenceGraph.h
Normal file
@@ -0,0 +1,258 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _INTERFERENCE_GRAPH_H_
|
||||
#define _INTERFERENCE_GRAPH_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "ControlGraph.h"
|
||||
#include "Primitives.h"
|
||||
#include "Instruction.h"
|
||||
#include "VirtualRegister.h"
|
||||
#include "RegisterPressure.h"
|
||||
#include "SparseSet.h"
|
||||
#include <string.h>
|
||||
|
||||
struct InterferenceVector
|
||||
{
|
||||
Uint32 count;
|
||||
InterferenceVector* next;
|
||||
RegisterName* neighbors;
|
||||
|
||||
InterferenceVector() : count(0), next(NULL) {}
|
||||
};
|
||||
|
||||
class RegisterAllocator;
|
||||
|
||||
template <class RegisterPressure>
|
||||
class InterferenceGraph
|
||||
{
|
||||
private:
|
||||
|
||||
RegisterAllocator& registerAllocator;
|
||||
|
||||
RegisterPressure::Set* interferences;
|
||||
InterferenceVector** vector;
|
||||
Uint32* offset;
|
||||
Uint32 rangeCount;
|
||||
|
||||
private:
|
||||
|
||||
// No copy constructor.
|
||||
InterferenceGraph(const InterferenceGraph&);
|
||||
// No copy operator.
|
||||
void operator = (const InterferenceGraph&);
|
||||
|
||||
// Check if reg is a member of the universe.
|
||||
void checkMember(RegisterName name) {assert(name < rangeCount);}
|
||||
// Return the edge index for the interference between name1 and name2.
|
||||
Uint32 getEdgeIndex(RegisterName name1, RegisterName name2);
|
||||
|
||||
public:
|
||||
InterferenceGraph(RegisterAllocator& registerAllocator) : registerAllocator(registerAllocator) {}
|
||||
|
||||
// Calculate the interferences.
|
||||
void build();
|
||||
// Return true if reg1 and reg2 interfere.
|
||||
bool interfere(RegisterName name1, RegisterName name2);
|
||||
// Return the interference vector for the given register or NULL if there is none.
|
||||
InterferenceVector* getInterferenceVector(RegisterName name) {return vector[name];}
|
||||
// Set the interference between name1 and name2.
|
||||
void setInterference(RegisterName name1, RegisterName name2);
|
||||
// Set the interference vector for the given register.
|
||||
void setInterferenceVector(RegisterName name, InterferenceVector* v) {vector[name] = v;}
|
||||
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
// Print the interferences.
|
||||
void printPretty(LogModuleObject log);
|
||||
#endif // DEBUG_LOG
|
||||
};
|
||||
|
||||
template <class RegisterPressure>
|
||||
void InterferenceGraph<RegisterPressure>::build()
|
||||
{
|
||||
Pool& pool = registerAllocator.pool;
|
||||
Uint32 rangeCount = registerAllocator.rangeCount;
|
||||
this->rangeCount = rangeCount;
|
||||
|
||||
// Initialize the structures.
|
||||
//
|
||||
offset = new(pool) Uint32[rangeCount + 1];
|
||||
vector = new(pool) InterferenceVector*[rangeCount];
|
||||
memset(vector, '\0', sizeof(InterferenceVector*) * rangeCount);
|
||||
|
||||
Uint32 o = 0;
|
||||
offset[0] = 0;
|
||||
for (Uint32 i = 1; i <= rangeCount; ++i) {
|
||||
offset[i] = o;
|
||||
o += i;
|
||||
}
|
||||
|
||||
interferences = new(pool) RegisterPressure::Set(pool, (rangeCount * rangeCount) / 2);
|
||||
|
||||
ControlGraph& controlGraph = registerAllocator.controlGraph;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
RegisterName* name2range = registerAllocator.name2range;
|
||||
LivenessInfo<RegisterPressure> liveness = Liveness<RegisterPressure>::analysis(controlGraph, rangeCount, name2range);
|
||||
registerAllocator.liveness = liveness;
|
||||
SparseSet currentLive(pool, rangeCount);
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
ControlNode& node = *nodes[n];
|
||||
currentLive = liveness.liveOut[n];
|
||||
|
||||
InstructionList& instructions = node.getInstructions();
|
||||
for (InstructionList::iterator i = instructions.end(); !instructions.done(i); i = instructions.retreat(i)) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
|
||||
InstructionUse* useBegin = instruction.getInstructionUseBegin();
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
InstructionUse* usePtr;
|
||||
InstructionDefine* defineBegin = instruction.getInstructionDefineBegin();
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
InstructionDefine* definePtr;
|
||||
|
||||
// Handle the copy instruction to avoid unnecessary interference between the 2 registers.
|
||||
if ((instruction.getFlags() & ifCopy) != 0) {
|
||||
assert(useBegin != useEnd && useBegin[0].isRegister());
|
||||
currentLive.clear(name2range[useBegin[0].getRegisterName()]);
|
||||
}
|
||||
|
||||
// Create the interferences.
|
||||
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister()) {
|
||||
RegisterName define = name2range[definePtr->getRegisterName()];
|
||||
|
||||
for (SparseSet::iterator e = currentLive.begin(); !currentLive.done(e); e = currentLive.advance(e)) {
|
||||
RegisterName live = RegisterName(currentLive.get(e));
|
||||
|
||||
if ((live != define) && !interfere(live, define) && registerAllocator.canInterfere(live, define)) {
|
||||
|
||||
if (vector[define] == NULL)
|
||||
vector[define] = new(pool) InterferenceVector();
|
||||
vector[define]->count++;
|
||||
|
||||
if (vector[live] == NULL)
|
||||
vector[live] = new(pool) InterferenceVector();
|
||||
vector[live]->count++;
|
||||
|
||||
setInterference(live, define);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Now update the liveness.
|
||||
//
|
||||
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister())
|
||||
currentLive.clear(name2range[definePtr->getRegisterName()]);
|
||||
|
||||
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister())
|
||||
currentLive.set(name2range[usePtr->getRegisterName()]);
|
||||
}
|
||||
}
|
||||
|
||||
// Allocate the memory to store the interferences.
|
||||
//
|
||||
for (Uint32 e = 0; e < rangeCount; e++)
|
||||
if (vector[e] != NULL) {
|
||||
InterferenceVector& v = *vector[e];
|
||||
v.neighbors = new(pool) RegisterName[v.count];
|
||||
v.count = 0;
|
||||
}
|
||||
|
||||
// Initialize the edges.
|
||||
//
|
||||
if (RegisterPressure::Set::isOrdered()) {
|
||||
RegisterName name1 = RegisterName(0);
|
||||
|
||||
for (RegisterPressure::Set::iterator i = interferences->begin(); !interferences->done(i); i = interferences->advance(i)) {
|
||||
Uint32 interferenceIndex = interferences->get(i);
|
||||
|
||||
while(interferenceIndex >= offset[name1 + 1])
|
||||
name1 = RegisterName(name1 + 1);
|
||||
|
||||
assert((interferenceIndex >= offset[name1]) && (interferenceIndex < offset[name1 + 1]));
|
||||
|
||||
RegisterName name2 = RegisterName(interferenceIndex - offset[name1]);
|
||||
|
||||
assert(interfere(name1, name2));
|
||||
|
||||
InterferenceVector& vector1 = *vector[name1];
|
||||
vector1.neighbors[vector1.count++] = name2;
|
||||
|
||||
InterferenceVector& vector2 = *vector[name2];
|
||||
vector2.neighbors[vector2.count++] = name1;
|
||||
}
|
||||
} else {
|
||||
trespass("not Implemented"); // FIX: need one more pass to initialize the vectors.
|
||||
}
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
Uint32 InterferenceGraph<RegisterPressure>::getEdgeIndex(RegisterName name1, RegisterName name2)
|
||||
{
|
||||
checkMember(name1); checkMember(name2);
|
||||
assert(name1 != name2); // This is not possible.
|
||||
return (name1 < name2) ? offset[name2] + name1 : offset[name1] + name2;
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
void InterferenceGraph<RegisterPressure>::setInterference(RegisterName name1, RegisterName name2)
|
||||
{
|
||||
interferences->set(getEdgeIndex(name1, name2));
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
bool InterferenceGraph<RegisterPressure>::interfere(RegisterName name1, RegisterName name2)
|
||||
{
|
||||
return interferences->test(getEdgeIndex(name1, name2));
|
||||
}
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
template <class RegisterPressure>
|
||||
void InterferenceGraph<RegisterPressure>::printPretty(LogModuleObject log)
|
||||
{
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Interference Vectors:\n"));
|
||||
for (Uint32 i = 1; i < rangeCount; i++) {
|
||||
if (vector[i] != NULL) {
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\tvr%d: (", i));
|
||||
for (InterferenceVector* v = vector[i]; v != NULL; v = v->next)
|
||||
for (Uint32 j = 0; j < v->count; j++) {
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("%d", v->neighbors[j]));
|
||||
if (v->next != NULL || j != (v->count - 1))
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, (","));
|
||||
}
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, (")\n"));
|
||||
}
|
||||
}
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Interference Matrix:\n"));
|
||||
for (RegisterName name1 = RegisterName(1); name1 < rangeCount; name1 = RegisterName(name1 + 1)) {
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\t%d:\t", name1));
|
||||
for (RegisterName name2 = RegisterName(1); name2 < rangeCount; name2 = RegisterName(name2 + 1))
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("%c", ((name1 != name2) && interfere(name1, name2)) ? '1' : '0'));
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\n"));
|
||||
}
|
||||
}
|
||||
#endif // DEBUG_LOG
|
||||
|
||||
#endif // _INTERFERENCE_GRAPH_H_
|
||||
87
mozilla/ef/Compiler/RegisterAllocator/LiveRange.h
Normal file
87
mozilla/ef/Compiler/RegisterAllocator/LiveRange.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _LIVE_RANGE_H_
|
||||
#define _LIVE_RANGE_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "ControlGraph.h"
|
||||
#include "ControlNodes.h"
|
||||
#include "Primitives.h"
|
||||
#include "Instruction.h"
|
||||
#include "RegisterAllocator.h"
|
||||
#include "RegisterAllocatorTools.h"
|
||||
|
||||
template <class RegisterPressure>
|
||||
struct LiveRange
|
||||
{
|
||||
static void build(RegisterAllocator& registerAllocator);
|
||||
};
|
||||
|
||||
template <class RegisterPressure>
|
||||
void LiveRange<RegisterPressure>::build(RegisterAllocator& registerAllocator)
|
||||
{
|
||||
// Intialize the lookup table.
|
||||
//
|
||||
Uint32 nameCount = registerAllocator.nameCount;
|
||||
RegisterName* nameTable = new(registerAllocator.pool) RegisterName[2*nameCount];
|
||||
RegisterName* rangeName = &nameTable[nameCount];
|
||||
|
||||
init(rangeName, nameCount);
|
||||
|
||||
// Walk the graph.
|
||||
//
|
||||
ControlGraph& controlGraph = registerAllocator.controlGraph;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
SparseSet destination(registerAllocator.pool, nameCount);
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
InstructionList& phiNodes = nodes[n]->getPhiNodeInstructions();
|
||||
|
||||
destination.clear();
|
||||
for (InstructionList::iterator i = phiNodes.begin(); !phiNodes.done(i); i = phiNodes.advance(i)) {
|
||||
Instruction& phiNode = phiNodes.get(i);
|
||||
assert(phiNode.getInstructionDefineBegin() != phiNode.getInstructionDefineEnd() && phiNode.getInstructionDefineBegin()[0].isRegister());
|
||||
destination.set(findRoot(phiNode.getInstructionDefineBegin()[0].getRegisterName(), rangeName));
|
||||
}
|
||||
|
||||
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
|
||||
Instruction& phiNode = phiNodes.get(p);
|
||||
|
||||
assert(phiNode.getInstructionDefineBegin() != phiNode.getInstructionDefineEnd() && phiNode.getInstructionDefineBegin()[0].isRegister());
|
||||
RegisterName destinationName = phiNode.getInstructionDefineBegin()[0].getRegisterName();
|
||||
RegisterName destinationRoot = findRoot(destinationName, rangeName);
|
||||
|
||||
InstructionUse* useEnd = phiNode.getInstructionUseEnd();
|
||||
for (InstructionUse* usePtr = phiNode.getInstructionUseBegin(); usePtr < useEnd; usePtr++) {
|
||||
assert(usePtr->isRegister());
|
||||
RegisterName sourceName = usePtr->getRegisterName();
|
||||
RegisterName sourceRoot = findRoot(sourceName, rangeName);
|
||||
|
||||
if (sourceRoot != destinationRoot && !destination.test(sourceRoot))
|
||||
rangeName[sourceRoot] = destinationRoot;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
registerAllocator.rangeCount = compress(registerAllocator.name2range, rangeName, nameCount, nameCount);
|
||||
}
|
||||
|
||||
#endif // _LIVE_RANGE_H_
|
||||
163
mozilla/ef/Compiler/RegisterAllocator/LiveRangeGraph.h
Normal file
163
mozilla/ef/Compiler/RegisterAllocator/LiveRangeGraph.h
Normal file
@@ -0,0 +1,163 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _LIVE_RANGE_GRAPH_
|
||||
#define _LIVE_RANGE_GRAPH_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "Pool.h"
|
||||
#include "ControlGraph.h"
|
||||
#include "ControlNodes.h"
|
||||
#include "Instruction.h"
|
||||
#include "RegisterTypes.h"
|
||||
|
||||
class RegisterAllocator;
|
||||
|
||||
template <class RegisterPressure>
|
||||
class LiveRangeGraph
|
||||
{
|
||||
private:
|
||||
|
||||
RegisterAllocator& registerAllocator;
|
||||
|
||||
RegisterPressure::Set* edges;
|
||||
Uint32 rangeCount;
|
||||
|
||||
public:
|
||||
//
|
||||
//
|
||||
LiveRangeGraph(RegisterAllocator& registerAllocator) : registerAllocator(registerAllocator) {}
|
||||
|
||||
//
|
||||
//
|
||||
void build();
|
||||
|
||||
//
|
||||
//
|
||||
void addEdge(RegisterName name1, RegisterName name2);
|
||||
|
||||
//
|
||||
//
|
||||
bool haveEdge(RegisterName name1, RegisterName name2);
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
//
|
||||
//
|
||||
void printPretty(LogModuleObject log);
|
||||
#endif // DEBUG_LOG
|
||||
};
|
||||
|
||||
template <class RegisterPressure>
|
||||
void LiveRangeGraph<RegisterPressure>::build()
|
||||
{
|
||||
Pool& pool = registerAllocator.pool;
|
||||
Uint32 rangeCount = registerAllocator.rangeCount;
|
||||
this->rangeCount = rangeCount;
|
||||
|
||||
edges = new(pool) RegisterPressure::Set(pool, rangeCount * rangeCount);
|
||||
|
||||
ControlGraph& controlGraph = registerAllocator.controlGraph;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
RegisterName* name2range = registerAllocator.name2range;
|
||||
LivenessInfo<RegisterPressure>& liveness = registerAllocator.liveness;
|
||||
SparseSet currentLive(pool, rangeCount);
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
ControlNode& node = *nodes[n];
|
||||
currentLive = liveness.liveOut[n];
|
||||
|
||||
InstructionList& instructions = node.getInstructions();
|
||||
for (InstructionList::iterator i = instructions.end(); !instructions.done(i); i = instructions.retreat(i)) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
|
||||
InstructionUse* useBegin = instruction.getInstructionUseBegin();
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
InstructionUse* usePtr;
|
||||
InstructionDefine* defineBegin = instruction.getInstructionDefineBegin();
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
InstructionDefine* definePtr;
|
||||
|
||||
if ((instruction.getFlags() & ifCopy) != 0) {
|
||||
assert(useBegin != useEnd && useBegin[0].isRegister());
|
||||
currentLive.clear(name2range[useBegin[0].getRegisterName()]);
|
||||
}
|
||||
|
||||
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister()) {
|
||||
RegisterName define = name2range[definePtr->getRegisterName()];
|
||||
|
||||
for (SparseSet::iterator l = currentLive.begin(); !currentLive.done(l); l = currentLive.advance(l)) {
|
||||
RegisterName live = RegisterName(currentLive.get(l));
|
||||
if (define != live && registerAllocator.canInterfere(define, live))
|
||||
addEdge(define, live);
|
||||
}
|
||||
}
|
||||
|
||||
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister())
|
||||
currentLive.clear(name2range[definePtr->getRegisterName()]);
|
||||
|
||||
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister())
|
||||
currentLive.set(name2range[usePtr->getRegisterName()]);
|
||||
|
||||
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister()) {
|
||||
RegisterName use = name2range[usePtr->getRegisterName()];
|
||||
|
||||
for (SparseSet::iterator l = currentLive.begin(); !currentLive.done(l); l = currentLive.advance(l)) {
|
||||
RegisterName live = RegisterName(currentLive.get(l));
|
||||
if (use != live && registerAllocator.canInterfere(use, live))
|
||||
addEdge(use, live);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
void LiveRangeGraph<RegisterPressure>::addEdge(RegisterName name1, RegisterName name2)
|
||||
{
|
||||
assert(name1 != name2);
|
||||
edges->set(name1 * rangeCount + name2);
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
bool LiveRangeGraph<RegisterPressure>::haveEdge(RegisterName name1, RegisterName name2)
|
||||
{
|
||||
assert(name1 != name2);
|
||||
return edges->test(name1 * rangeCount + name2);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
template <class RegisterPressure>
|
||||
void LiveRangeGraph<RegisterPressure>::printPretty(LogModuleObject log)
|
||||
{
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Live ranges graph:\n"));
|
||||
for (RegisterName name1 = RegisterName(1); name1 < rangeCount; name1 = RegisterName(name1 + 1)) {
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\t%d:\t", name1));
|
||||
for (RegisterName name2 = RegisterName(1); name2 < rangeCount; name2 = RegisterName(name2 + 1))
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("%c", ((name1 != name2) && haveEdge(name1, name2)) ? '1' : '0'));
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\n"));
|
||||
}
|
||||
}
|
||||
#endif // DEBUG_LOG
|
||||
|
||||
#endif // _LIVE_RANGE_GRAPH_
|
||||
21
mozilla/ef/Compiler/RegisterAllocator/Liveness.cpp
Normal file
21
mozilla/ef/Compiler/RegisterAllocator/Liveness.cpp
Normal file
@@ -0,0 +1,21 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "Liveness.h"
|
||||
|
||||
301
mozilla/ef/Compiler/RegisterAllocator/Liveness.h
Normal file
301
mozilla/ef/Compiler/RegisterAllocator/Liveness.h
Normal file
@@ -0,0 +1,301 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _LIVENESS_H_
|
||||
#define _LIVENESS_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "ControlGraph.h"
|
||||
#include "ControlNodes.h"
|
||||
#include "Instruction.h"
|
||||
#include "RegisterTypes.h"
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// LivenessInfo -
|
||||
|
||||
template <class RegisterPressure>
|
||||
struct LivenessInfo
|
||||
{
|
||||
RegisterPressure::Set* liveIn;
|
||||
RegisterPressure::Set* liveOut;
|
||||
DEBUG_LOG_ONLY(Uint32 size);
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
void printPretty(LogModuleObject log);
|
||||
#endif // DEBUG_LOG
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Liveness
|
||||
//
|
||||
// The liveness is defined by the following data-flow equations:
|
||||
//
|
||||
// LiveIn(n) = LocalLive(n) U (LiveOut(n) - Killed(n)).
|
||||
// LiveOut(n) = U LiveIn(s) (s a successor of n).
|
||||
//
|
||||
// where LocalLive(n) is the set of used registers in the block n, Killed(n)
|
||||
// is the set of defined registers in the block n, LiveIn(n) is the set of
|
||||
// live registers at the begining of the block n and LiveOut(n) is the set
|
||||
// of live registers at the end of the block n.
|
||||
//
|
||||
//
|
||||
// We will compute the liveness analysis in two stages:
|
||||
//
|
||||
// 1- Build LocalLive(n) (wich is an approximation of LiveIn(n)) and Killed(n)
|
||||
// for each block n.
|
||||
// 2- Perform a backward data-flow analysis to propagate the liveness information
|
||||
// through the entire control-flow graph.
|
||||
//
|
||||
|
||||
template <class RegisterPressure>
|
||||
struct Liveness
|
||||
{
|
||||
static LivenessInfo<RegisterPressure> analysis(ControlGraph& controlGraph, Uint32 rangeCount, const RegisterName* name2range);
|
||||
static LivenessInfo<RegisterPressure> analysis(ControlGraph& controlGraph, Uint32 nameCount);
|
||||
};
|
||||
|
||||
template <class RegisterPressure>
|
||||
LivenessInfo<RegisterPressure> Liveness<RegisterPressure>::analysis(ControlGraph& controlGraph, Uint32 rangeCount, const RegisterName* name2range)
|
||||
{
|
||||
Pool& pool = controlGraph.pool;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
// Allocate the temporary sets.
|
||||
RegisterPressure::Set* killed = new(pool) RegisterPressure::Set[nNodes](pool, rangeCount);
|
||||
|
||||
// Allocate the globals sets.
|
||||
RegisterPressure::Set* liveIn = new(pool) RegisterPressure::Set[nNodes](pool, rangeCount);
|
||||
RegisterPressure::Set* liveOut = new(pool) RegisterPressure::Set[nNodes](pool, rangeCount);
|
||||
|
||||
// First stage of the liveness analysis: Compute the sets LocalLive(stored in LiveIn) and Killed.
|
||||
//
|
||||
for (Uint32 n = 0; n < (nNodes - 1); n++) {
|
||||
ControlNode& node = *nodes[n];
|
||||
|
||||
RegisterPressure::Set& currentLocalLive = liveIn[n];
|
||||
RegisterPressure::Set& currentKilled = killed[n];
|
||||
|
||||
// Find the instructions contributions to the sets LocalLive and Killed.
|
||||
//
|
||||
InstructionList& instructions = node.getInstructions();
|
||||
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
|
||||
// If a VirtualRegister is 'used' before being 'defined' then we add it to set LocalLive.
|
||||
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister()) {
|
||||
Uint32 index = name2range[usePtr->getRegisterName()];
|
||||
|
||||
if (!currentKilled.test(index))
|
||||
currentLocalLive.set(index);
|
||||
}
|
||||
|
||||
// If a Virtualregister is 'defined' then we add it to the set Killed.
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister())
|
||||
currentKilled.set(name2range[definePtr->getRegisterName()]);
|
||||
}
|
||||
}
|
||||
|
||||
// Second stage of the liveness analysis: We propagate the LiveIn & LiveOut through the entire
|
||||
// control-flow graph.
|
||||
//
|
||||
RegisterPressure::Set temp(pool, rangeCount);
|
||||
|
||||
bool changed;
|
||||
do {
|
||||
changed = false;
|
||||
|
||||
// For all nodes is this graph except the endNode.
|
||||
for (Int32 n = (nNodes - 2); n >= 0; n--) {
|
||||
ControlNode& node = *nodes[n];
|
||||
|
||||
RegisterPressure::Set& currentLiveIn = liveIn[n];
|
||||
RegisterPressure::Set& currentLiveOut = liveOut[n];
|
||||
|
||||
// Compute temp = Union of LiveIn(s) (s a successor of this node) | usedByPhiNodes(n).
|
||||
// temp will be the new LiveOut(n).
|
||||
Uint32 nSuccessors = node.nSuccessors();
|
||||
if (nSuccessors != 0) {
|
||||
temp = liveIn[node.nthSuccessor(0).getTarget().dfsNum];
|
||||
for (Uint32 s = 1; s < nSuccessors; s++)
|
||||
temp |= liveIn[node.nthSuccessor(s).getTarget().dfsNum];
|
||||
} else
|
||||
temp.clear();
|
||||
|
||||
// If temp and LiveOut(n) differ then set LiveOut(n) = temp and recalculate the
|
||||
// new LiveIn(n).
|
||||
if (currentLiveOut != temp) {
|
||||
currentLiveOut = temp;
|
||||
temp -= killed[n]; // FIX: could be optimized with one call to unionDiff !
|
||||
temp |= currentLiveIn;
|
||||
|
||||
if (currentLiveIn != temp) {
|
||||
currentLiveIn = temp;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while(changed);
|
||||
|
||||
LivenessInfo<RegisterPressure> liveness;
|
||||
liveness.liveIn = liveIn;
|
||||
liveness.liveOut = liveOut;
|
||||
DEBUG_LOG_ONLY(liveness.size = nNodes);
|
||||
return liveness;
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
LivenessInfo<RegisterPressure> Liveness<RegisterPressure>::analysis(ControlGraph& controlGraph, Uint32 nameCount)
|
||||
{
|
||||
Pool& pool = controlGraph.pool;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
// Allocate the temporary sets.
|
||||
RegisterPressure::Set* killed = new(pool) RegisterPressure::Set[nNodes](pool, nameCount);
|
||||
RegisterPressure::Set* usedByPhiNodes = NULL;
|
||||
|
||||
// Allocate the globals sets.
|
||||
RegisterPressure::Set* liveIn = new(pool) RegisterPressure::Set[nNodes](pool, nameCount);
|
||||
RegisterPressure::Set* liveOut = new(pool) RegisterPressure::Set[nNodes](pool, nameCount);
|
||||
|
||||
// First stage of the liveness analysis: Compute the sets LocalLive(stored in LiveIn) and Killed.
|
||||
//
|
||||
for (Uint32 n = 0; n < (nNodes - 1); n++) {
|
||||
ControlNode& node = *nodes[n];
|
||||
|
||||
RegisterPressure::Set& currentLocalLive = liveIn[n];
|
||||
RegisterPressure::Set& currentKilled = killed[n];
|
||||
|
||||
InstructionList& phiNodes = node.getPhiNodeInstructions();
|
||||
|
||||
if ((usedByPhiNodes == NULL) && !phiNodes.empty())
|
||||
usedByPhiNodes = new(pool) RegisterPressure::Set[nNodes](pool, nameCount);
|
||||
|
||||
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
|
||||
Instruction& phiNode = phiNodes.get(p);
|
||||
|
||||
InstructionDefine& define = phiNode.getInstructionDefineBegin()[0];
|
||||
currentKilled.set(define.getRegisterName());
|
||||
|
||||
typedef DoublyLinkedList<ControlEdge> ControlEdgeList;
|
||||
const ControlEdgeList& predecessors = node.getPredecessors();
|
||||
ControlEdgeList::iterator p = predecessors.begin();
|
||||
InstructionUse* useEnd = phiNode.getInstructionUseEnd();
|
||||
for (InstructionUse* usePtr = phiNode.getInstructionUseBegin(); usePtr < useEnd; usePtr++, p = predecessors.advance(p))
|
||||
if (usePtr->isRegister())
|
||||
usedByPhiNodes[predecessors.get(p).getSource().dfsNum].set(usePtr->getRegisterName());
|
||||
}
|
||||
|
||||
// Find the instructions contributions to the sets LocalLive and Killed.
|
||||
//
|
||||
InstructionList& instructions = node.getInstructions();
|
||||
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
|
||||
// If a VirtualRegister is 'used' before being 'defined' then we add it to set LocalLive.
|
||||
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister()) {
|
||||
Uint32 index = usePtr->getRegisterName();
|
||||
|
||||
if (!currentKilled.test(index))
|
||||
currentLocalLive.set(index);
|
||||
}
|
||||
|
||||
// If a Virtualregister is 'defined' then we add it to the set Killed.
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister())
|
||||
currentKilled.set(definePtr->getRegisterName());
|
||||
}
|
||||
}
|
||||
|
||||
// Second stage of the liveness analysis: We propagate the LiveIn & LiveOut through the entire
|
||||
// control-flow graph.
|
||||
//
|
||||
RegisterPressure::Set temp(pool, nameCount);
|
||||
|
||||
bool changed;
|
||||
do {
|
||||
changed = false;
|
||||
|
||||
// For all nodes is this graph except the endNode.
|
||||
for (Int32 n = (nNodes - 2); n >= 0; n--) {
|
||||
ControlNode& node = *nodes[n];
|
||||
|
||||
RegisterPressure::Set& currentLiveIn = liveIn[n];
|
||||
RegisterPressure::Set& currentLiveOut = liveOut[n];
|
||||
|
||||
// Compute temp = Union of LiveIn(s) (s a successor of this node) | usedByPhiNodes(n).
|
||||
// temp will be the new LiveOut(n).
|
||||
Uint32 nSuccessors = node.nSuccessors();
|
||||
if (nSuccessors != 0) {
|
||||
temp = liveIn[node.nthSuccessor(0).getTarget().dfsNum];
|
||||
for (Uint32 s = 1; s < nSuccessors; s++)
|
||||
temp |= liveIn[node.nthSuccessor(s).getTarget().dfsNum];
|
||||
} else
|
||||
temp.clear();
|
||||
|
||||
// Insert the phiNodes contribution.
|
||||
if (usedByPhiNodes != NULL)
|
||||
temp |= usedByPhiNodes[n];
|
||||
|
||||
// If temp and LiveOut(n) differ then set LiveOut(n) = temp and recalculate the
|
||||
// new LiveIn(n).
|
||||
if (currentLiveOut != temp) {
|
||||
currentLiveOut = temp;
|
||||
temp -= killed[n]; // FIX: could be optimized with one call to unionDiff !
|
||||
temp |= currentLiveIn;
|
||||
|
||||
if (currentLiveIn != temp) {
|
||||
currentLiveIn = temp;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while(changed);
|
||||
|
||||
LivenessInfo<RegisterPressure> liveness;
|
||||
liveness.liveIn = liveIn;
|
||||
liveness.liveOut = liveOut;
|
||||
DEBUG_LOG_ONLY(liveness.size = nNodes);
|
||||
return liveness;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
template <class RegisterPressure>
|
||||
void LivenessInfo<RegisterPressure>::printPretty(LogModuleObject log)
|
||||
{
|
||||
for (Uint32 n = 0; n < size; n++) {
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Node N%d:\n\tliveIn = ", n));
|
||||
liveIn[n].printPretty(log);
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\tliveOut = "));
|
||||
liveOut[n].printPretty(log);
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\n"));
|
||||
}
|
||||
}
|
||||
#endif // DEBUG_LOG
|
||||
|
||||
#endif // _LIVENESS_H_
|
||||
40
mozilla/ef/Compiler/RegisterAllocator/Makefile
Normal file
40
mozilla/ef/Compiler/RegisterAllocator/Makefile
Normal file
@@ -0,0 +1,40 @@
|
||||
#! gmake
|
||||
|
||||
DEPTH = ../..
|
||||
|
||||
MODULE_NAME = RegisterAllocator
|
||||
|
||||
include $(DEPTH)/config/config.mk
|
||||
|
||||
INCLUDES += \
|
||||
-I$(DEPTH)/Utilities/General \
|
||||
-I$(DEPTH)/Utilities/zlib \
|
||||
-I$(DEPTH)/Runtime/ClassReader \
|
||||
-I$(DEPTH)/Runtime/NativeMethods \
|
||||
-I$(DEPTH)/Runtime/System \
|
||||
-I$(DEPTH)/Runtime/ClassInfo \
|
||||
-I$(DEPTH)/Runtime/FileReader \
|
||||
-I$(DEPTH)/Compiler/PrimitiveGraph \
|
||||
-I$(DEPTH)/Compiler/FrontEnd \
|
||||
-I$(DEPTH)/Compiler/Optimizer \
|
||||
-I$(DEPTH)/Compiler/CodeGenerator \
|
||||
-I$(DEPTH)/Compiler/CodeGenerator/md \
|
||||
-I$(DEPTH)/Compiler/CodeGenerator/md/$(CPU_ARCH) \
|
||||
-I$(DEPTH)/Compiler/RegisterAllocator \
|
||||
-I$(DEPTH)/Driver/StandAloneJava \
|
||||
-I$(DEPTH)/Debugger \
|
||||
$(NULL)
|
||||
|
||||
CXXSRCS = \
|
||||
RegisterAllocator.cpp \
|
||||
RegisterAllocatorTools.cpp \
|
||||
DominatorGraph.cpp \
|
||||
VirtualRegister.cpp \
|
||||
BitSet.cpp \
|
||||
SparseSet.cpp \
|
||||
$(NULL)
|
||||
|
||||
|
||||
include $(DEPTH)/config/rules.mk
|
||||
|
||||
libs:: $(MODULE)
|
||||
392
mozilla/ef/Compiler/RegisterAllocator/PhiNodeRemover.h
Normal file
392
mozilla/ef/Compiler/RegisterAllocator/PhiNodeRemover.h
Normal file
@@ -0,0 +1,392 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _PHI_NODE_REMOVER_H_
|
||||
#define _PHI_NODE_REMOVER_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "Pool.h"
|
||||
#include "ControlGraph.h"
|
||||
#include "DominatorGraph.h"
|
||||
#include "VirtualRegister.h"
|
||||
#include "RegisterPressure.h"
|
||||
#include "Liveness.h"
|
||||
#include "Instruction.h"
|
||||
#include "InstructionEmitter.h"
|
||||
#include "SparseSet.h"
|
||||
#include <string.h>
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// RegisterNameNode -
|
||||
|
||||
struct RegisterNameNode
|
||||
{
|
||||
RegisterNameNode* next;
|
||||
RegisterName newName;
|
||||
Uint32 nextPushed;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// CopyData -
|
||||
|
||||
struct CopyData
|
||||
{
|
||||
RegisterName source;
|
||||
RegisterClassKind classKind;
|
||||
Uint32 useCount;
|
||||
bool isLiveOut;
|
||||
RegisterName sourceNameToUse;
|
||||
RegisterName temporaryName;
|
||||
RegisterNameNode* newName;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// PhiNodeRemover<RegisterPressure> -
|
||||
|
||||
template <class RegisterPressure>
|
||||
struct PhiNodeRemover
|
||||
{
|
||||
// Replace the phi nodes by copy instructions.
|
||||
static void replacePhiNodes(ControlGraph& controlGraph, VirtualRegisterManager& vrManager, InstructionEmitter& emitter);
|
||||
};
|
||||
|
||||
// Split some of the critical edges and return true if there are still some
|
||||
// in the graph after that.
|
||||
//
|
||||
static bool splitCriticalEdges(ControlGraph& /*cg*/)
|
||||
{
|
||||
// FIX: not implemented.
|
||||
return true;
|
||||
}
|
||||
|
||||
inline void pushName(Pool& pool, RegisterNameNode** stack, SparseSet& pushed, Uint32* nodeListPointer, RegisterName oldName, RegisterName newName)
|
||||
{
|
||||
RegisterNameNode& newNode = *new(pool) RegisterNameNode();
|
||||
|
||||
if (pushed.test(oldName))
|
||||
(*stack)->newName = newName;
|
||||
else {
|
||||
newNode.newName = newName;
|
||||
newNode.nextPushed = *nodeListPointer;
|
||||
*nodeListPointer = oldName;
|
||||
newNode.next = *stack;
|
||||
*stack = &newNode;
|
||||
pushed.set(oldName);
|
||||
}
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
void PhiNodeRemover<RegisterPressure>::replacePhiNodes(ControlGraph& controlGraph, VirtualRegisterManager& vrManager, InstructionEmitter& emitter)
|
||||
{
|
||||
Pool& pool = controlGraph.pool;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
// Initialize the local variables.
|
||||
//
|
||||
|
||||
// When we insert the copies we will also need to create new VirtualRegisters for
|
||||
// the insertion of temporaries. The maximum number of temporary register will not
|
||||
// exceed the number of phiNodes in the primitive graph.
|
||||
Uint32 nameCount = vrManager.getSize();
|
||||
Uint32 maxNameCount = nameCount;
|
||||
for (Uint32 n = 0; n < nNodes; n++)
|
||||
maxNameCount += nodes[n]->getPhiNodes().length();
|
||||
|
||||
// If the CFG contains some critical edges (backward edge which source has more than one
|
||||
// outgoing edge and destination has more than one incomimg edge) then we need the liveness
|
||||
// information to be able to insert temporary copies.
|
||||
RegisterPressure::Set* liveOut = NULL;
|
||||
if (splitCriticalEdges(controlGraph))
|
||||
liveOut = Liveness<LowRegisterPressure>::analysis(controlGraph, nameCount).liveOut;
|
||||
|
||||
DominatorGraph dGraph(controlGraph);
|
||||
|
||||
SparseSet pushed(pool, maxNameCount);
|
||||
SparseSet destinationList(pool, maxNameCount);
|
||||
SparseSet workList(pool, maxNameCount);
|
||||
|
||||
CopyData* copyStats = new(pool) CopyData[maxNameCount];
|
||||
memset(copyStats, '\0', maxNameCount*sizeof(CopyData));
|
||||
|
||||
struct NodeStack {
|
||||
Uint32* next;
|
||||
Uint32* limit;
|
||||
Uint32 pushedList;
|
||||
};
|
||||
|
||||
// Allocate the node stack and initialize the node stack pointer.
|
||||
NodeStack* nodeStack = new(pool) NodeStack[nNodes + 1];
|
||||
NodeStack* nodeStackPtr = nodeStack;
|
||||
|
||||
// We start by the begin node.
|
||||
Uint32 startNode = 0;
|
||||
Uint32* next = &startNode;
|
||||
Uint32* limit = &startNode + 1;
|
||||
|
||||
while (true) {
|
||||
|
||||
if (next == limit) {
|
||||
// If there are no more node in the sibling, we have to pop the current
|
||||
// frame from the stack and update the copyStats of the pushed nodes.
|
||||
//
|
||||
if (nodeStackPtr == nodeStack)
|
||||
// We are at the bottom of the stack and there are no more nodes
|
||||
// to look at. We are done !
|
||||
break;
|
||||
|
||||
--nodeStackPtr;
|
||||
// We are done with all the children of this node in the dominator tree.
|
||||
// We need to update the copy information of all the new names pushed
|
||||
// during the walk over this node.
|
||||
Uint32 pushedList = nodeStackPtr->pushedList;
|
||||
while (pushedList != 0) {
|
||||
Uint32 nextName = copyStats[pushedList].newName->nextPushed;
|
||||
copyStats[pushedList].newName = copyStats[pushedList].newName->next;
|
||||
pushedList = nextName;
|
||||
}
|
||||
|
||||
// restore the previous frame.
|
||||
next = nodeStackPtr->next;
|
||||
limit = nodeStackPtr->limit;
|
||||
} else {
|
||||
Uint32 currentNode = *next++;
|
||||
Uint32 pushedList = 0;
|
||||
|
||||
|
||||
// Initialize the sets.
|
||||
pushed.clear();
|
||||
destinationList.clear();
|
||||
|
||||
// STEP1:
|
||||
// Walk the instruction list and to replace all the instruction uses with their new name.
|
||||
// If the instruction is a phi node and its defined register is alive at the end of this
|
||||
// block then we push the defined register into the stack.
|
||||
//
|
||||
ControlNode& node = *nodes[currentNode];
|
||||
RegisterPressure::Set* currentLiveOut = (liveOut != NULL) ? &liveOut[currentNode] : (RegisterPressure::Set*) 0;
|
||||
|
||||
InstructionList& phiNodes = node.getPhiNodeInstructions();
|
||||
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
|
||||
Instruction& phiNode = phiNodes.get(p);
|
||||
|
||||
InstructionUse* useEnd = phiNode.getInstructionUseEnd();
|
||||
for (InstructionUse* usePtr = phiNode.getInstructionUseBegin(); usePtr < useEnd; usePtr++) {
|
||||
assert(usePtr->isRegister());
|
||||
RegisterName name = usePtr->getRegisterName();
|
||||
|
||||
if (copyStats[name].newName != NULL && copyStats[name].newName->newName != name)
|
||||
usePtr->setRegisterName(copyStats[name].newName->newName);
|
||||
}
|
||||
|
||||
if (currentLiveOut != NULL) {
|
||||
// This is a phi node and we have to push its defined name if it is live
|
||||
// at the end of the node. We only need to do this if the CFG has critical edges.
|
||||
assert(phiNode.getInstructionDefineBegin() != phiNode.getInstructionDefineEnd() && phiNode.getInstructionDefineBegin()[0].isRegister());
|
||||
RegisterName name = phiNode.getInstructionDefineBegin()[0].getRegisterName();
|
||||
|
||||
if (currentLiveOut->test(name))
|
||||
pushName(pool, &(copyStats[name].newName), pushed, &pushedList, name, name);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
InstructionList& instructions = node.getInstructions();
|
||||
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister()) {
|
||||
RegisterName name = usePtr->getRegisterName();
|
||||
|
||||
if (copyStats[name].newName != NULL && copyStats[name].newName->newName != name)
|
||||
usePtr->setRegisterName(copyStats[name].newName->newName);
|
||||
}
|
||||
}
|
||||
|
||||
// STEP2:
|
||||
// Look at this node's successors' phiNodes. We keep track of the number of time
|
||||
// a VR will be used by another copy instruction and insert each definition into the
|
||||
// destinationList. This is the only pass over this node's successors as we will
|
||||
// get all the information we need in the CopyData structures.
|
||||
//
|
||||
ControlEdge* successorEdgeEnd = node.getSuccessorsEnd();
|
||||
for (ControlEdge* successorEdgePtr = node.getSuccessorsBegin(); successorEdgePtr < successorEdgeEnd; successorEdgePtr++) {
|
||||
Uint32 useIndex = successorEdgePtr->getIndex();
|
||||
ControlNode& successor = successorEdgePtr->getTarget();
|
||||
|
||||
// Look at its phi nodes. The phi nodes are at the top of the instruction list. We exit
|
||||
// as soon as we find an instruction which is not a phi node
|
||||
InstructionList& phiNodes = successor.getPhiNodeInstructions();
|
||||
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
|
||||
Instruction& phiNode = phiNodes.get(p);
|
||||
|
||||
assert((phiNode.getInstructionUseBegin() + useIndex) < phiNode.getInstructionUseEnd());
|
||||
assert(phiNode.getInstructionDefineBegin() != phiNode.getInstructionDefineEnd());
|
||||
|
||||
InstructionUse& source = phiNode.getInstructionUseBegin()[useIndex];
|
||||
InstructionDefine& destination = phiNode.getInstructionDefineBegin()[0];
|
||||
|
||||
assert(source.isRegister() && destination.isRegister());
|
||||
|
||||
RegisterName sourceName = source.getRegisterName();
|
||||
RegisterName destinationName = destination.getRegisterName();
|
||||
|
||||
// Get the correct name for the source.
|
||||
if (copyStats[sourceName].newName != NULL)
|
||||
sourceName = copyStats[sourceName].newName->newName;
|
||||
|
||||
// Update the CopyData structures.
|
||||
if ((sourceName != rnInvalid) && (sourceName != destinationName)) {
|
||||
copyStats[destinationName].source = sourceName;
|
||||
copyStats[destinationName].classKind = destination.getRegisterClass();
|
||||
copyStats[destinationName].isLiveOut = (currentLiveOut != NULL) ? currentLiveOut->test(destinationName) : false;
|
||||
copyStats[destinationName].sourceNameToUse = destinationName;
|
||||
copyStats[sourceName].sourceNameToUse = sourceName;
|
||||
copyStats[sourceName].useCount++;
|
||||
destinationList.set(destinationName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// STEP3:
|
||||
// Insert into the worklist only the destination registers that will be not used in
|
||||
// another copy instruction in this block.
|
||||
//
|
||||
assert(workList.getSize() == 0);
|
||||
for (SparseSet::iterator d = destinationList.begin(); !destinationList.done(d); d = destinationList.advance(d)) {
|
||||
Uint32 dest = destinationList.get(d);
|
||||
if (copyStats[dest].useCount == 0)
|
||||
workList.set(dest);
|
||||
}
|
||||
|
||||
// STEP4:
|
||||
// Insert the copy instructions.
|
||||
//
|
||||
Uint32 destinationListSize = destinationList.getSize();
|
||||
InstructionList::iterator endOfTheNode = instructions.end();
|
||||
|
||||
// Find the right place to insert the copy instructions.
|
||||
if (destinationListSize != 0)
|
||||
while (instructions.get(endOfTheNode).getFlags() & ifControl)
|
||||
endOfTheNode = instructions.retreat(endOfTheNode);
|
||||
|
||||
while (destinationListSize != 0) {
|
||||
while(workList.getSize()) {
|
||||
RegisterName destinationName = RegisterName(workList.getOne());
|
||||
RegisterName sourceName = copyStats[destinationName].source;
|
||||
|
||||
workList.clear(destinationName);
|
||||
if (copyStats[destinationName].isLiveOut && !copyStats[destinationName].temporaryName) {
|
||||
// Lost copy problem.
|
||||
copyStats[destinationName].isLiveOut = false;
|
||||
|
||||
RegisterName sourceName = destinationName;
|
||||
RegisterClassKind classKind = copyStats[sourceName].classKind;
|
||||
RegisterName destinationName = getName(vrManager.newVirtualRegister(classKind));
|
||||
assert(destinationName < maxNameCount);
|
||||
|
||||
copyStats[destinationName].classKind = classKind;
|
||||
copyStats[sourceName].useCount = 0;
|
||||
|
||||
// We need to insert a copy to a temporary register to keep the
|
||||
// source register valid at the end of the node defining it.
|
||||
// This copy will be inserted right after the phi node defining it.
|
||||
RegisterName from = copyStats[sourceName].sourceNameToUse;
|
||||
Instruction* definingPhiNode = vrManager.getVirtualRegister(from).getDefiningInstruction();
|
||||
assert(definingPhiNode && (definingPhiNode->getFlags() & ifPhiNode) != 0);
|
||||
|
||||
RegisterID fromID = buildRegisterID(from, classKind);
|
||||
RegisterID toID = buildRegisterID(destinationName, classKind);
|
||||
Instruction& copy = emitter.newCopy(*definingPhiNode->getPrimitive(), fromID, toID);
|
||||
vrManager.getVirtualRegister(destinationName).setDefiningInstruction(copy);
|
||||
definingPhiNode->getPrimitive()->getContainer()->getInstructions().addFirst(copy);
|
||||
|
||||
copyStats[sourceName].temporaryName = destinationName;
|
||||
copyStats[sourceName].sourceNameToUse = destinationName;
|
||||
pushName(pool, &(copyStats[sourceName].newName), pushed, &pushedList, sourceName, destinationName);
|
||||
}
|
||||
|
||||
// Insert the copy instruction at the end of the current node.
|
||||
RegisterName from = copyStats[sourceName].sourceNameToUse;
|
||||
|
||||
RegisterClassKind classKind = copyStats[destinationName].classKind;
|
||||
RegisterID fromID = buildRegisterID(from, classKind);
|
||||
RegisterID toID = buildRegisterID(destinationName, classKind);
|
||||
Instruction& copy = emitter.newCopy(*vrManager.getVirtualRegister(from).getDefiningInstruction()->getPrimitive(), fromID, toID);
|
||||
instructions.insertAfter(copy, endOfTheNode);
|
||||
endOfTheNode = instructions.advance(endOfTheNode);
|
||||
|
||||
copyStats[sourceName].useCount = 0;
|
||||
if (destinationList.test(sourceName) && copyStats[sourceName].isLiveOut)
|
||||
pushName(pool, &(copyStats[sourceName].newName), pushed, &pushedList, sourceName, destinationName);
|
||||
copyStats[sourceName].isLiveOut = false;
|
||||
copyStats[sourceName].sourceNameToUse = destinationName;
|
||||
|
||||
if (destinationList.test(sourceName))
|
||||
workList.set(sourceName);
|
||||
destinationList.clear(destinationName);
|
||||
}
|
||||
|
||||
destinationListSize = destinationList.getSize();
|
||||
if (destinationListSize != 0) {
|
||||
RegisterName sourceName = RegisterName(destinationList.getOne());
|
||||
RegisterName destinationName;
|
||||
|
||||
if (!copyStats[sourceName].temporaryName) {
|
||||
// Cycle problem.
|
||||
RegisterClassKind classKind = copyStats[sourceName].classKind;
|
||||
destinationName = getName(vrManager.newVirtualRegister(classKind));
|
||||
assert(destinationName < maxNameCount);
|
||||
|
||||
copyStats[destinationName].classKind = classKind;
|
||||
copyStats[sourceName].temporaryName = destinationName;
|
||||
|
||||
// Insert the copy instruction at the end of the current node.
|
||||
RegisterName from = copyStats[sourceName].sourceNameToUse;
|
||||
|
||||
RegisterID fromID = buildRegisterID(from, classKind);
|
||||
RegisterID toID = buildRegisterID(destinationName, classKind);
|
||||
Instruction& copy = emitter.newCopy(*vrManager.getVirtualRegister(from).getDefiningInstruction()->getPrimitive(), fromID, toID);
|
||||
vrManager.getVirtualRegister(destinationName).setDefiningInstruction(copy);
|
||||
instructions.insertAfter(copy, endOfTheNode);
|
||||
endOfTheNode = instructions.advance(endOfTheNode);
|
||||
} else
|
||||
destinationName = copyStats[sourceName].temporaryName;
|
||||
|
||||
copyStats[sourceName].useCount = 0;
|
||||
copyStats[sourceName].isLiveOut = false;
|
||||
copyStats[sourceName].sourceNameToUse = destinationName;
|
||||
pushName(pool, &(copyStats[sourceName].newName), pushed, &pushedList, sourceName, destinationName);
|
||||
|
||||
workList.set(sourceName);
|
||||
}
|
||||
}
|
||||
|
||||
nodeStackPtr->pushedList = pushedList;
|
||||
nodeStackPtr->next = next;
|
||||
nodeStackPtr->limit = limit;
|
||||
++nodeStackPtr;
|
||||
next = dGraph.getSuccessorsBegin(currentNode);
|
||||
limit = dGraph.getSuccessorsEnd(currentNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // _PHI_NODE_REMOVER_H_
|
||||
155
mozilla/ef/Compiler/RegisterAllocator/RegisterAllocator.cpp
Normal file
155
mozilla/ef/Compiler/RegisterAllocator/RegisterAllocator.cpp
Normal file
@@ -0,0 +1,155 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "LogModule.h"
|
||||
#include "RegisterAllocator.h"
|
||||
#include "RegisterPressure.h"
|
||||
#include "RegisterAllocatorTools.h"
|
||||
#include "PhiNodeRemover.h"
|
||||
#include "LiveRange.h"
|
||||
#include "Liveness.h"
|
||||
#include "InterferenceGraph.h"
|
||||
#include "LiveRangeGraph.h"
|
||||
#include "Coalescing.h"
|
||||
#include "Spilling.h"
|
||||
#include "Coloring.h"
|
||||
#include "Splits.h"
|
||||
|
||||
class Pool;
|
||||
class ControlGraph;
|
||||
class VirtualRegisterManager;
|
||||
class InstructionEmitter;
|
||||
|
||||
UT_DEFINE_LOG_MODULE(RegAlloc);
|
||||
|
||||
void RegisterAllocator::allocateRegisters(Pool& pool, ControlGraph& controlGraph, VirtualRegisterManager& vrManager, InstructionEmitter& emitter)
|
||||
{
|
||||
// Insert the phi node instructions. We want to do this to have a single defined register per instruction.
|
||||
// If we keep the PhiNode (as a DataNode) and a PhiNode is of DoubleWordKind then we have to execute
|
||||
// some special code for the high word annotation.
|
||||
//
|
||||
RegisterAllocatorTools::insertPhiNodeInstructions(controlGraph, emitter);
|
||||
|
||||
// Perform some tests on the instruction graph.
|
||||
//
|
||||
DEBUG_ONLY(RegisterAllocatorTools::testTheInstructionGraph(controlGraph, vrManager));
|
||||
|
||||
// Replace the phi node instructions by their equivalent copy instructions.
|
||||
//
|
||||
PhiNodeRemover<LowRegisterPressure>::replacePhiNodes(controlGraph, vrManager, emitter);
|
||||
|
||||
// Do the register allocation.
|
||||
//
|
||||
RegisterAllocator registerAllocator(pool, controlGraph, vrManager, emitter);
|
||||
registerAllocator.doGraphColoring();
|
||||
}
|
||||
|
||||
void RegisterAllocator::doGraphColoring()
|
||||
{
|
||||
// Initialize the liverange map.
|
||||
//
|
||||
initLiveRanges();
|
||||
|
||||
// Build the live ranges. We do this to compress the number of RegisterNames
|
||||
// used in the insterference graph.
|
||||
//
|
||||
LiveRange<LowRegisterPressure>::build(*this);
|
||||
|
||||
// Remove unnecessary copies.
|
||||
//
|
||||
RegisterAllocatorTools::removeUnnecessaryCopies(*this);
|
||||
|
||||
for (Uint8 loop = 0; loop < 10; loop++) {
|
||||
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("********* RegisterAllocator loop %d *********\n", loop));
|
||||
|
||||
while(true) {
|
||||
// Build the interference graph.
|
||||
//
|
||||
iGraph.build();
|
||||
|
||||
// Coalesce the copy instructions.
|
||||
//
|
||||
if (!Coalescing<LowRegisterPressure>::coalesce(*this))
|
||||
break;
|
||||
}
|
||||
|
||||
// Print the interference graph.
|
||||
//
|
||||
DEBUG_LOG_ONLY(iGraph.printPretty(UT_LOG_MODULE(RegAlloc)));
|
||||
|
||||
// Calculate the spill costs.
|
||||
//
|
||||
Spilling<LowRegisterPressure>::calculateSpillCosts(*this);
|
||||
DEBUG_LOG_ONLY(RegisterAllocatorTools::printSpillCosts(*this));
|
||||
|
||||
// Calculate the split costs.
|
||||
//
|
||||
Splits<LowRegisterPressure>::calculateSplitCosts(*this);
|
||||
DEBUG_LOG_ONLY(RegisterAllocatorTools::printSplitCosts(*this));
|
||||
|
||||
// Build the live range graph.
|
||||
//
|
||||
lGraph.build();
|
||||
DEBUG_LOG_ONLY(lGraph.printPretty(UT_LOG_MODULE(RegAlloc)));
|
||||
|
||||
// Color the graph. If it succeeds then we're done with the
|
||||
// register allocation.
|
||||
//
|
||||
if (Coloring<LowRegisterPressure>::color(*this)) {
|
||||
// Write the final colors in the instruction graph.
|
||||
//
|
||||
Coloring<LowRegisterPressure>::finalColoring(*this);
|
||||
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("********** RegisterAllocator done **********\n"));
|
||||
DEBUG_LOG_ONLY(RegisterAllocatorTools::printInstructions(*this));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// We need to spill some registers.
|
||||
//
|
||||
Spilling<LowRegisterPressure>::insertSpillCode(*this);
|
||||
|
||||
// Insert the split instructions.
|
||||
//
|
||||
Splits<LowRegisterPressure>::insertSplitCode(*this);
|
||||
|
||||
// Update the live ranges.
|
||||
//
|
||||
// FIX
|
||||
}
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
RegisterAllocatorTools::updateInstructionGraph(*this);
|
||||
RegisterAllocatorTools::printInstructions(*this);
|
||||
#endif
|
||||
fprintf(stderr, "!!! Coloring failed after 10 loops !!!\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
void RegisterAllocator::initLiveRanges()
|
||||
{
|
||||
Uint32 count = this->nameCount;
|
||||
RegisterName* name2range = new(pool) RegisterName[nameCount];
|
||||
for (RegisterName r = RegisterName(1); r < count; r = RegisterName(r + 1))
|
||||
name2range[r] = r;
|
||||
this->name2range = name2range;
|
||||
rangeCount = count;
|
||||
}
|
||||
88
mozilla/ef/Compiler/RegisterAllocator/RegisterAllocator.h
Normal file
88
mozilla/ef/Compiler/RegisterAllocator/RegisterAllocator.h
Normal file
@@ -0,0 +1,88 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _REGISTER_ALLOCATOR_H_
|
||||
#define _REGISTER_ALLOCATOR_H_
|
||||
|
||||
class Pool;
|
||||
class ControlGraph;
|
||||
class InstructionEmitter;
|
||||
struct SpillCost;
|
||||
struct SplitCost;
|
||||
|
||||
#include "Liveness.h"
|
||||
#include "VirtualRegister.h"
|
||||
#include "RegisterPressure.h" // This should included by Backend.cpp
|
||||
#include "InterferenceGraph.h"
|
||||
#include "LiveRangeGraph.h"
|
||||
|
||||
//template <class RegisterPressure>
|
||||
class RegisterAllocator
|
||||
{
|
||||
public:
|
||||
|
||||
Pool& pool; //
|
||||
ControlGraph& controlGraph; //
|
||||
VirtualRegisterManager& vrManager; //
|
||||
InstructionEmitter& emitter; //
|
||||
|
||||
RegisterName* name2range; //
|
||||
RegisterName* color; //
|
||||
SpillCost* spillCost; //
|
||||
SparseSet* willSpill; //
|
||||
SplitCost* splitCost; //
|
||||
NameLinkedList** splitAround; //
|
||||
InterferenceGraph<LowRegisterPressure> iGraph; //
|
||||
LiveRangeGraph<LowRegisterPressure> lGraph; //
|
||||
LivenessInfo<LowRegisterPressure> liveness; //
|
||||
Uint32 nameCount; //
|
||||
Uint32 rangeCount; //
|
||||
bool splitFound; //
|
||||
|
||||
private:
|
||||
|
||||
//
|
||||
//
|
||||
void doGraphColoring();
|
||||
|
||||
public:
|
||||
|
||||
//
|
||||
//
|
||||
inline RegisterAllocator(Pool& pool, ControlGraph& controlGraph, VirtualRegisterManager& vrManager, InstructionEmitter& emitter);
|
||||
|
||||
//
|
||||
//
|
||||
bool canInterfere(RegisterName /*name1*/, RegisterName /*name2*/) const {return true;}
|
||||
|
||||
//
|
||||
//
|
||||
void initLiveRanges();
|
||||
|
||||
//
|
||||
//
|
||||
static void allocateRegisters(Pool& pool, ControlGraph& controlGraph, VirtualRegisterManager& vrManager, InstructionEmitter& emitter);
|
||||
};
|
||||
|
||||
//
|
||||
//
|
||||
inline RegisterAllocator::RegisterAllocator(Pool& pool, ControlGraph& controlGraph, VirtualRegisterManager& vrManager, InstructionEmitter& emitter)
|
||||
: pool(pool), controlGraph(controlGraph), vrManager(vrManager), emitter(emitter), iGraph(*this), lGraph(*this), nameCount(vrManager.getSize()) {}
|
||||
|
||||
#endif // _REGISTER_ALLOCATOR_H_
|
||||
|
||||
355
mozilla/ef/Compiler/RegisterAllocator/RegisterAllocatorTools.cpp
Normal file
355
mozilla/ef/Compiler/RegisterAllocator/RegisterAllocatorTools.cpp
Normal file
@@ -0,0 +1,355 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "LogModule.h"
|
||||
#include "RegisterAllocatorTools.h"
|
||||
#include "Pool.h"
|
||||
#include "ControlGraph.h"
|
||||
#include "ControlNodes.h"
|
||||
#include "Primitives.h"
|
||||
#include "InstructionEmitter.h"
|
||||
#include "Instruction.h"
|
||||
#include "RegisterAllocator.h"
|
||||
#include "Spilling.h"
|
||||
#include "Splits.h"
|
||||
#include "BitSet.h"
|
||||
|
||||
UT_EXTERN_LOG_MODULE(RegAlloc);
|
||||
|
||||
#ifdef DEBUG
|
||||
void RegisterAllocatorTools::testTheInstructionGraph(ControlGraph& controlGraph, VirtualRegisterManager& vrManager)
|
||||
{
|
||||
// Test the declared VirtualRegisters. The register allocator tries to condense the register universe.
|
||||
// Any gap in the VirtualRegister names will be a loss of efficiency !!!!
|
||||
|
||||
Uint32 nameCount = vrManager.getSize();
|
||||
BitSet registerSeen(controlGraph.pool, nameCount);
|
||||
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
|
||||
InstructionList& instructions = nodes[n]->getInstructions();
|
||||
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister())
|
||||
registerSeen.set(usePtr->getRegisterName());
|
||||
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister())
|
||||
registerSeen.set(definePtr->getRegisterName());
|
||||
}
|
||||
|
||||
InstructionList& phiNodes = nodes[n]->getPhiNodeInstructions();
|
||||
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
|
||||
Instruction& instruction = phiNodes.get(p);
|
||||
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister())
|
||||
registerSeen.set(usePtr->getRegisterName());
|
||||
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister())
|
||||
registerSeen.set(definePtr->getRegisterName());
|
||||
}
|
||||
}
|
||||
|
||||
bool renameRegisters = false;
|
||||
for (BitSet::iterator i = registerSeen.nextZero(0); !registerSeen.done(i); i = registerSeen.nextZero(i)) {
|
||||
renameRegisters = true;
|
||||
fprintf(stderr,
|
||||
"WARNING: The VirtualRegister vr%d has been allocated during CodeGeneration but\n"
|
||||
" is never used nor defined by any instruction in the instruction graph\n"
|
||||
" PLEASE FIX \n",
|
||||
i);
|
||||
}
|
||||
if (renameRegisters) {
|
||||
Instruction** definingInstruction = new Instruction*[nameCount];
|
||||
memset(definingInstruction, '\0', nameCount * sizeof(Instruction*));
|
||||
RegisterName* newName = new RegisterName[nameCount];
|
||||
memset(newName, '\0', nameCount * sizeof(RegisterName));
|
||||
RegisterName nextName = RegisterName(1);
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
|
||||
InstructionList& instructions = nodes[n]->getInstructions();
|
||||
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister()) {
|
||||
RegisterName name = usePtr->getRegisterName();
|
||||
if (newName[name] == rnInvalid) {
|
||||
newName[name] = nextName;
|
||||
definingInstruction[nextName] = vrManager.getVirtualRegister(name).getDefiningInstruction();
|
||||
nextName = RegisterName(nextName + 1);
|
||||
}
|
||||
usePtr->setRegisterName(newName[name]);
|
||||
}
|
||||
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister()) {
|
||||
RegisterName name = definePtr->getRegisterName();
|
||||
if (newName[name] == rnInvalid) {
|
||||
newName[name] = nextName;
|
||||
definingInstruction[nextName] = vrManager.getVirtualRegister(name).getDefiningInstruction();
|
||||
nextName = RegisterName(nextName + 1);
|
||||
}
|
||||
definePtr->setRegisterName(newName[name]);
|
||||
}
|
||||
}
|
||||
|
||||
InstructionList& phiNodes = nodes[n]->getPhiNodeInstructions();
|
||||
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
|
||||
Instruction& instruction = phiNodes.get(p);
|
||||
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister()) {
|
||||
RegisterName name = usePtr->getRegisterName();
|
||||
if (newName[name] == rnInvalid) {
|
||||
newName[name] = nextName;
|
||||
definingInstruction[nextName] = vrManager.getVirtualRegister(name).getDefiningInstruction();
|
||||
nextName = RegisterName(nextName + 1);
|
||||
}
|
||||
usePtr->setRegisterName(newName[name]);
|
||||
}
|
||||
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister()) {
|
||||
RegisterName name = definePtr->getRegisterName();
|
||||
if (newName[name] == rnInvalid) {
|
||||
newName[name] = nextName;
|
||||
definingInstruction[nextName] = vrManager.getVirtualRegister(name).getDefiningInstruction();
|
||||
nextName = RegisterName(nextName + 1);
|
||||
}
|
||||
definePtr->setRegisterName(newName[name]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vrManager.setSize(nextName);
|
||||
|
||||
for (RegisterName r = RegisterName(1); r < nextName; r = RegisterName(r + 1))
|
||||
vrManager.getVirtualRegister(r).definingInstruction = definingInstruction[r];
|
||||
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("RegisterMap:\n"));
|
||||
for (Uint32 i = 1; i < nameCount; i++)
|
||||
if (newName[i] != 0)
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\tvr%d becomes vr%d.\n", i, newName[i]));
|
||||
else
|
||||
UT_OBJECTLOG(UT_LOG_MODULE(RegAlloc), PR_LOG_ALWAYS, ("\tvr%d is dead.\n", i));
|
||||
|
||||
|
||||
delete newName;
|
||||
delete definingInstruction;
|
||||
}
|
||||
|
||||
}
|
||||
#endif // DEBUG
|
||||
|
||||
void RegisterAllocatorTools::removeUnnecessaryCopies(RegisterAllocator& registerAllocator)
|
||||
{
|
||||
ControlGraph& controlGraph = registerAllocator.controlGraph;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
RegisterName* name2range = registerAllocator.name2range;
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
InstructionList& instructions = nodes[n]->getInstructions();
|
||||
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i);) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
i = instructions.advance(i);
|
||||
|
||||
if (instruction.getFlags() & ifCopy) {
|
||||
assert(instruction.getInstructionUseBegin() != instruction.getInstructionUseEnd() && instruction.getInstructionUseBegin()[0].isRegister());
|
||||
assert(instruction.getInstructionDefineBegin() != instruction.getInstructionDefineEnd() && instruction.getInstructionDefineBegin()[0].isRegister());
|
||||
|
||||
RegisterName source = name2range[instruction.getInstructionUseBegin()[0].getRegisterName()];
|
||||
RegisterName destination = name2range[instruction.getInstructionDefineBegin()[0].getRegisterName()];
|
||||
|
||||
if (source == destination)
|
||||
instruction.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RegisterAllocatorTools::updateInstructionGraph(RegisterAllocator& registerAllocator)
|
||||
{
|
||||
ControlGraph& controlGraph = registerAllocator.controlGraph;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
RegisterName* name2range = registerAllocator.name2range;
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
InstructionList& instructions = nodes[n]->getInstructions();
|
||||
for (InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister())
|
||||
usePtr->setRegisterName(name2range[usePtr->getRegisterName()]);
|
||||
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister())
|
||||
definePtr->setRegisterName(name2range[definePtr->getRegisterName()]);
|
||||
}
|
||||
|
||||
InstructionList& phiNodes = nodes[n]->getPhiNodeInstructions();
|
||||
for (InstructionList::iterator p = phiNodes.begin(); !phiNodes.done(p); p = phiNodes.advance(p)) {
|
||||
Instruction& instruction = phiNodes.get(p);
|
||||
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
for (InstructionUse* usePtr = instruction.getInstructionUseBegin(); usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister())
|
||||
usePtr->setRegisterName(name2range[usePtr->getRegisterName()]);
|
||||
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
for (InstructionDefine* definePtr = instruction.getInstructionDefineBegin(); definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister())
|
||||
definePtr->setRegisterName(name2range[definePtr->getRegisterName()]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RegisterAllocatorTools::insertPhiNodeInstructions(ControlGraph& controlGraph, InstructionEmitter& emitter)
|
||||
{
|
||||
Pool& pool = controlGraph.pool;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
ControlNode& node = *nodes[n];
|
||||
DoublyLinkedList<PhiNode>& phiNodes = node.getPhiNodes();
|
||||
|
||||
if (!phiNodes.empty()) {
|
||||
|
||||
// Set the index of the incoming edges.
|
||||
Uint32 index = 0;
|
||||
const DoublyLinkedList<ControlEdge>& predecessors = node.getPredecessors();
|
||||
for (DoublyLinkedList<ControlEdge>::iterator p = predecessors.begin(); !predecessors.done(p); p = predecessors.advance(p))
|
||||
predecessors.get(p).setIndex(index++);
|
||||
|
||||
// Insert the phi node instruction in the instruction list.
|
||||
for (DoublyLinkedList<PhiNode>::iterator i = phiNodes.begin(); !phiNodes.done(i); i = phiNodes.advance(i)) {
|
||||
PhiNode& phiNode = phiNodes.get(i);
|
||||
ValueKind kind = phiNode.getKind();
|
||||
|
||||
if (!isStorableKind(kind))
|
||||
continue;
|
||||
|
||||
RegisterClassKind classKind = rckGeneral; // FIX: get class kind from phi node kind.
|
||||
Uint32 nInputs = phiNode.nInputs();
|
||||
|
||||
PhiNodeInstruction& phiNodeInstruction = *new(pool) PhiNodeInstruction(&phiNode, pool, nInputs);
|
||||
|
||||
emitter.defineProducer(phiNode, phiNodeInstruction, 0, classKind, drLow);
|
||||
for (Uint32 whichInput = 0; whichInput < nInputs; whichInput++)
|
||||
emitter.useProducer(phiNode.nthInputVariable(whichInput), phiNodeInstruction, whichInput, classKind, drLow);
|
||||
|
||||
node.addPhiNodeInstruction(phiNodeInstruction);
|
||||
|
||||
if (isDoublewordKind(kind)) {
|
||||
PhiNodeInstruction& phiNodeInstruction = *new(pool) PhiNodeInstruction(&phiNode, pool, nInputs);
|
||||
|
||||
emitter.defineProducer(phiNode, phiNodeInstruction, 0, classKind, drHigh);
|
||||
for (Uint32 whichInput = 0; whichInput < nInputs; whichInput++)
|
||||
emitter.useProducer(phiNode.nthInputVariable(whichInput), phiNodeInstruction, whichInput, classKind, drHigh);
|
||||
|
||||
node.addPhiNodeInstruction(phiNodeInstruction);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
|
||||
void RegisterAllocatorTools::printSpillCosts(RegisterAllocator& registerAllocator)
|
||||
{
|
||||
LogModuleObject log = UT_LOG_MODULE(RegAlloc);
|
||||
Uint32 rangeCount = registerAllocator.rangeCount;
|
||||
SpillCost* cost = registerAllocator.spillCost;
|
||||
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Spill costs:\n"));
|
||||
for (Uint32 i = 1; i < rangeCount; i++) {
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\trange %d : ", i));
|
||||
if (cost[i].infinite)
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("infinite\n"));
|
||||
else
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("%f\n", cost[i].cost));
|
||||
}
|
||||
}
|
||||
|
||||
void RegisterAllocatorTools::printSplitCosts(RegisterAllocator& registerAllocator)
|
||||
{
|
||||
LogModuleObject log = UT_LOG_MODULE(RegAlloc);
|
||||
Uint32 rangeCount = registerAllocator.rangeCount;
|
||||
SplitCost* cost = registerAllocator.splitCost;
|
||||
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("Split costs:\n"));
|
||||
for (Uint32 i = 1; i < rangeCount; i++) {
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\trange %d : loads = %f stores = %f\n", i, cost[i].loads, cost[i].stores));
|
||||
}
|
||||
}
|
||||
|
||||
void RegisterAllocatorTools::printInstructions(RegisterAllocator& registerAllocator)
|
||||
{
|
||||
LogModuleObject log = UT_LOG_MODULE(RegAlloc);
|
||||
ControlNode** nodes = registerAllocator.controlGraph.dfsList;
|
||||
Uint32 nNodes = registerAllocator.controlGraph.nNodes;
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("N%d:\n", n));
|
||||
|
||||
InstructionList& phiNodes = nodes[n]->getPhiNodeInstructions();
|
||||
InstructionList& instructions = nodes[n]->getInstructions();
|
||||
|
||||
if (!phiNodes.empty()) {
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, (" PhiNodes:\n", n));
|
||||
for(InstructionList::iterator i = phiNodes.begin(); !phiNodes.done(i); i = phiNodes.advance(i)) {
|
||||
phiNodes.get(i).printPretty(log);
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\n"));
|
||||
}
|
||||
if (!instructions.empty())
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, (" Instructions:\n", n));
|
||||
}
|
||||
|
||||
for(InstructionList::iterator i = instructions.begin(); !instructions.done(i); i = instructions.advance(i)) {
|
||||
instructions.get(i).printPretty(log);
|
||||
UT_OBJECTLOG(log, PR_LOG_ALWAYS, ("\n"));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // DEBUG_LOG
|
||||
117
mozilla/ef/Compiler/RegisterAllocator/RegisterAllocatorTools.h
Normal file
117
mozilla/ef/Compiler/RegisterAllocator/RegisterAllocatorTools.h
Normal file
@@ -0,0 +1,117 @@
|
||||
// -*- mode:C++; tab-width:4; truncate-lines:t -*-
|
||||
//
|
||||
// CONFIDENTIAL AND PROPRIETARY SOURCE CODE OF
|
||||
// NETSCAPE COMMUNICATIONS CORPORATION
|
||||
// Copyright © 1996, 1997 Netscape Communications Corporation. All Rights
|
||||
// Reserved. Use of this Source Code is subject to the terms of the
|
||||
// applicable license agreement from Netscape Communications Corporation.
|
||||
// The copyright notice(s) in this Source Code does not indicate actual or
|
||||
// intended publication of this Source Code.
|
||||
//
|
||||
// $Id: RegisterAllocatorTools.h,v 1.1.2.1 1999-03-02 16:12:05 fur%netscape.com Exp $
|
||||
//
|
||||
|
||||
#ifndef _REGISTER_ALLOCATOR_TOOLS_H_
|
||||
#define _REGISTER_ALLOCATOR_TOOLS_H_
|
||||
|
||||
#include "LogModule.h"
|
||||
#include "RegisterTypes.h"
|
||||
#include <string.h>
|
||||
|
||||
class RegisterAllocator;
|
||||
class ControlGraph;
|
||||
class InstructionEmitter;
|
||||
class VirtualRegisterManager;
|
||||
|
||||
struct RegisterAllocatorTools
|
||||
{
|
||||
//
|
||||
//
|
||||
static void insertPhiNodeInstructions(ControlGraph& controlGraph, InstructionEmitter& emitter);
|
||||
|
||||
//
|
||||
//
|
||||
static void updateInstructionGraph(RegisterAllocator& registerAllocator);
|
||||
|
||||
//
|
||||
//
|
||||
static void removeUnnecessaryCopies(RegisterAllocator& registerAllocator);
|
||||
|
||||
#ifdef DEBUG
|
||||
//
|
||||
//
|
||||
static void testTheInstructionGraph(ControlGraph& controlGraph, VirtualRegisterManager& vrManager);
|
||||
#endif // DEBUG
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
//
|
||||
//
|
||||
static void printInstructions(RegisterAllocator& registerAllocator);
|
||||
|
||||
//
|
||||
//
|
||||
static void printSpillCosts(RegisterAllocator& registerAllocator);
|
||||
|
||||
//
|
||||
//
|
||||
static void printSplitCosts(RegisterAllocator& registerAllocator);
|
||||
#endif // DEBUG_LOG
|
||||
};
|
||||
|
||||
//
|
||||
// FIX: this should go in a class (LookupTable ?)
|
||||
//
|
||||
|
||||
inline RegisterName findRoot(RegisterName name, RegisterName* table)
|
||||
{
|
||||
RegisterName* stack = table;
|
||||
RegisterName* stackPtr = stack;
|
||||
|
||||
RegisterName newName;
|
||||
while((newName = table[name]) != name) {
|
||||
*--stackPtr = name;
|
||||
name = newName;
|
||||
}
|
||||
|
||||
while (stackPtr != stack)
|
||||
table[*stackPtr++] = name;
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
inline void init(RegisterName* table, Uint32 nameCount)
|
||||
{
|
||||
for (RegisterName r = RegisterName(0); r < nameCount; r = RegisterName(r + 1))
|
||||
table[r] = r;
|
||||
}
|
||||
|
||||
inline Uint32 compress(RegisterName* name2range, RegisterName* table, Uint32 nameCount, Uint32 tableSize)
|
||||
{
|
||||
RegisterName* liveRange = new RegisterName[tableSize];
|
||||
memset(liveRange, '\0', tableSize * sizeof(RegisterName));
|
||||
|
||||
// Update the lookup table.
|
||||
for (RegisterName r = RegisterName(1); r < tableSize; r = RegisterName(r + 1))
|
||||
findRoot(r, table);
|
||||
|
||||
// Count the liveranges.
|
||||
Uint32 liveRangeCount = 1;
|
||||
for (RegisterName s = RegisterName(1); s < tableSize; s = RegisterName(s + 1))
|
||||
if (table[s] == s)
|
||||
liveRange[s] = RegisterName(liveRangeCount++);
|
||||
|
||||
for (RegisterName t = RegisterName(1); t < nameCount; t = RegisterName(t + 1))
|
||||
name2range[t] = liveRange[table[name2range[t]]];
|
||||
|
||||
return liveRangeCount;
|
||||
}
|
||||
|
||||
inline double doLog10(Uint32 power)
|
||||
{
|
||||
double log = 1.0;
|
||||
while (power--)
|
||||
log *= 10.0;
|
||||
return log;
|
||||
}
|
||||
|
||||
#endif // _REGISTER_ALLOCATOR_TOOLS_H_
|
||||
38
mozilla/ef/Compiler/RegisterAllocator/RegisterAssigner.h
Normal file
38
mozilla/ef/Compiler/RegisterAllocator/RegisterAssigner.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _REGISTER_ASSIGNER_H_
|
||||
#define _REGISTER_ASSIGNER_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "VirtualRegister.h"
|
||||
|
||||
class FastBitMatrix;
|
||||
|
||||
class RegisterAssigner
|
||||
{
|
||||
protected:
|
||||
VirtualRegisterManager& vRegManager;
|
||||
|
||||
public:
|
||||
RegisterAssigner(VirtualRegisterManager& vrMan) : vRegManager(vrMan) {}
|
||||
|
||||
virtual bool assignRegisters(FastBitMatrix& interferenceMatrix) = 0;
|
||||
};
|
||||
|
||||
#endif /* _REGISTER_ASSIGNER_H_ */
|
||||
25
mozilla/ef/Compiler/RegisterAllocator/RegisterClass.h
Normal file
25
mozilla/ef/Compiler/RegisterAllocator/RegisterClass.h
Normal file
@@ -0,0 +1,25 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _REGISTER_CLASS_H_
|
||||
#define _REGISTER_CLASS_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "RegisterTypes.h"
|
||||
|
||||
#endif // _REGISTER_CLASS_H_
|
||||
37
mozilla/ef/Compiler/RegisterAllocator/RegisterPressure.h
Normal file
37
mozilla/ef/Compiler/RegisterAllocator/RegisterPressure.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _REGISTER_PRESSURE_H_
|
||||
#define _REGISTER_PRESSURE_H_
|
||||
|
||||
#include "BitSet.h"
|
||||
#include "HashSet.h"
|
||||
|
||||
struct LowRegisterPressure
|
||||
{
|
||||
typedef BitSet Set;
|
||||
static const bool setIsOrdered = true;
|
||||
};
|
||||
|
||||
struct HighRegisterPressure
|
||||
{
|
||||
typedef HashSet Set;
|
||||
static const bool setIsOrdered = false;
|
||||
};
|
||||
|
||||
#endif // _REGISTER_PRESSURE_H_
|
||||
104
mozilla/ef/Compiler/RegisterAllocator/RegisterTypes.h
Normal file
104
mozilla/ef/Compiler/RegisterAllocator/RegisterTypes.h
Normal file
@@ -0,0 +1,104 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _REGISTER_TYPES_H_
|
||||
#define _REGISTER_TYPES_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// RegisterName -
|
||||
//
|
||||
|
||||
enum RegisterName {
|
||||
rnInvalid = 0,
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// RegisterClassKind -
|
||||
//
|
||||
|
||||
enum RegisterClassKind {
|
||||
rckInvalid = 0,
|
||||
rckGeneral,
|
||||
rckStackSlot,
|
||||
|
||||
nRegisterClassKind
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// RegisterID -
|
||||
//
|
||||
|
||||
enum RegisterID {
|
||||
invalidID = 0
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// RegisterKind -
|
||||
//
|
||||
|
||||
enum RegisterKind {
|
||||
rkCallerSave = 0,
|
||||
rkCalleeSave,
|
||||
};
|
||||
|
||||
struct NameLinkedList {
|
||||
RegisterName name;
|
||||
NameLinkedList* next;
|
||||
};
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
const registerNameMask = 0x03ffffff;
|
||||
const coloredRegisterMask = 0x04000000;
|
||||
const machineRegisterMask = 0x08000000;
|
||||
const registerClassMask = 0xf0000000;
|
||||
|
||||
const registerNameShift = 0;
|
||||
const coloredRegisterShift = 26;
|
||||
const machineRegisterShift = 27;
|
||||
const registerClassShift = 28;
|
||||
|
||||
#else // DEBUG
|
||||
|
||||
const registerNameMask = 0x0fffffff;
|
||||
const registerClassMask = 0xf0000000;
|
||||
|
||||
const registerNameShift = 0;
|
||||
const registerClassShift = 28;
|
||||
|
||||
#endif // DEBUG
|
||||
|
||||
|
||||
inline RegisterClassKind getClass(RegisterID registerID) {return RegisterClassKind((registerID & registerClassMask) >> registerClassShift);}
|
||||
inline RegisterName getName(RegisterID registerID) {return RegisterName((registerID & registerNameMask) >> registerNameShift);}
|
||||
inline void setClass(RegisterID& registerID, RegisterClassKind classKind) {registerID = RegisterID((registerID & ~registerClassMask) | ((classKind << registerClassShift) & registerClassMask));}
|
||||
inline void setName(RegisterID& registerID, RegisterName name) {assert((name & ~registerNameMask) == 0); registerID = RegisterID((registerID & ~registerNameMask) | ((name << registerNameShift) & registerNameMask));}
|
||||
inline RegisterID buildRegisterID(RegisterName name, RegisterClassKind classKind) {return RegisterID(((classKind << registerClassShift) & registerClassMask) | ((name << registerNameShift) & registerNameMask));}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
inline bool isMachineRegister(RegisterID rid) {return (rid & machineRegisterMask) != 0;}
|
||||
inline void setMachineRegister(RegisterID& rid) {rid = RegisterID(rid | machineRegisterMask);}
|
||||
inline bool isColoredRegister(RegisterID rid) {return (rid & coloredRegisterMask) != 0;}
|
||||
inline void setColoredRegister(RegisterID& rid) {rid = RegisterID(rid | coloredRegisterMask);}
|
||||
|
||||
#endif // DEBUG
|
||||
|
||||
#endif // _REGISTER_TYPES_H_
|
||||
32
mozilla/ef/Compiler/RegisterAllocator/SSATools.cpp
Normal file
32
mozilla/ef/Compiler/RegisterAllocator/SSATools.cpp
Normal file
@@ -0,0 +1,32 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "SSATools.h"
|
||||
#include "ControlGraph.h"
|
||||
#include "VirtualRegister.h"
|
||||
#include "Liveness.h"
|
||||
|
||||
void replacePhiNodes(ControlGraph& controlGraph, VirtualRegisterManager& vrManager)
|
||||
{
|
||||
if (!controlGraph.hasBackEdges)
|
||||
return;
|
||||
|
||||
Liveness liveness(controlGraph.pool);
|
||||
liveness.buildLivenessAnalysis(controlGraph, vrManager);
|
||||
}
|
||||
29
mozilla/ef/Compiler/RegisterAllocator/SSATools.h
Normal file
29
mozilla/ef/Compiler/RegisterAllocator/SSATools.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _SSA_TOOLS_H_
|
||||
#define _SSA_TOOLS_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
|
||||
class ControlGraph;
|
||||
class VirtualRegisterManager;
|
||||
|
||||
extern void replacePhiNodes(ControlGraph& controlGraph, VirtualRegisterManager& vrManager);
|
||||
|
||||
#endif // _SSA_TOOLS_H_
|
||||
37
mozilla/ef/Compiler/RegisterAllocator/SparseSet.cpp
Normal file
37
mozilla/ef/Compiler/RegisterAllocator/SparseSet.cpp
Normal file
@@ -0,0 +1,37 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "SparseSet.h"
|
||||
#include "BitSet.h"
|
||||
#include "Pool.h"
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
// Print the set.
|
||||
//
|
||||
void SparseSet::printPretty(LogModuleObject log)
|
||||
{
|
||||
Pool pool;
|
||||
BitSet set(pool, universeSize);
|
||||
|
||||
for (Uint32 i = 0; i < count; i++)
|
||||
set.set(node[i].element);
|
||||
|
||||
set.printPretty(log);
|
||||
}
|
||||
#endif // DEBUG_LOG
|
||||
168
mozilla/ef/Compiler/RegisterAllocator/SparseSet.h
Normal file
168
mozilla/ef/Compiler/RegisterAllocator/SparseSet.h
Normal file
@@ -0,0 +1,168 @@
|
||||
// -*- mode:C++; tab-width:4; truncate-lines:t -*-
|
||||
//
|
||||
// CONFIDENTIAL AND PROPRIETARY SOURCE CODE OF
|
||||
// NETSCAPE COMMUNICATIONS CORPORATION
|
||||
// Copyright © 1996, 1997 Netscape Communications Corporation. All Rights
|
||||
// Reserved. Use of this Source Code is subject to the terms of the
|
||||
// applicable license agreement from Netscape Communications Corporation.
|
||||
// The copyright notice(s) in this Source Code does not indicate actual or
|
||||
// intended publication of this Source Code.
|
||||
//
|
||||
// $Id: SparseSet.h,v 1.1.2.1 1999-03-02 16:12:07 fur%netscape.com Exp $
|
||||
//
|
||||
|
||||
#ifndef _SPARSE_SET_H_
|
||||
#define _SPARSE_SET_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "Pool.h"
|
||||
#include "LogModule.h"
|
||||
#include "BitSet.h"
|
||||
|
||||
class SparseSet
|
||||
{
|
||||
private:
|
||||
|
||||
struct Node {
|
||||
Uint32 element;
|
||||
Uint32 stackIndex;
|
||||
};
|
||||
|
||||
Node* node;
|
||||
Uint32 count;
|
||||
Uint32 universeSize;
|
||||
|
||||
private:
|
||||
|
||||
// No copy constructor.
|
||||
SparseSet(const SparseSet&);
|
||||
|
||||
// Check if the given set's universe is of the same size than this universe.
|
||||
void checkUniverseCompatibility(const SparseSet& set) const {assert(set.universeSize == universeSize);}
|
||||
// Check if pos is valid for this set's universe.
|
||||
void checkMember(Int32 pos) const {assert(pos >=0 && Uint32(pos) < universeSize);}
|
||||
|
||||
public:
|
||||
|
||||
SparseSet(Pool& pool, Uint32 universeSize) : universeSize(universeSize) {node = new(pool) Node[universeSize]; clear();}
|
||||
|
||||
// Clear the sparse set.
|
||||
void clear() {count = 0;}
|
||||
// Clear the element at index.
|
||||
inline void clear(Uint32 index);
|
||||
// Set the element at index.
|
||||
inline void set(Uint32 index);
|
||||
// Return true if the element at index is set.
|
||||
inline bool test(Uint32 index) const;
|
||||
// Union with the given sparse set.
|
||||
inline void or(const SparseSet& set);
|
||||
// Intersection with the given sparse set.
|
||||
inline void and(const SparseSet& set);
|
||||
// Difference with the given sparse set.
|
||||
inline void difference(const SparseSet& set);
|
||||
// Copy set.
|
||||
inline SparseSet& operator = (const SparseSet& set);
|
||||
inline SparseSet& operator = (const BitSet& set);
|
||||
// Return true if the sparse sets are identical.
|
||||
friend bool operator == (const SparseSet& set1, const SparseSet& set2);
|
||||
// Return true if the sparse sets are different.
|
||||
friend bool operator != (const SparseSet& set1, const SparseSet& set2);
|
||||
|
||||
// Logical operators.
|
||||
SparseSet& operator |= (const SparseSet& set) {or(set); return *this;}
|
||||
SparseSet& operator &= (const SparseSet& set) {and(set); return *this;}
|
||||
SparseSet& operator -= (const SparseSet& set) {difference(set); return *this;}
|
||||
|
||||
// Iterator to conform with the set API.
|
||||
typedef Int32 iterator;
|
||||
// Return the iterator for the first element of this set.
|
||||
iterator begin() const {return count - 1;}
|
||||
// Return the next iterator.
|
||||
iterator advance(iterator pos) const {return --pos;}
|
||||
// Return true if the iterator is at the end of the set.
|
||||
bool done(iterator pos) const {return pos < 0;}
|
||||
// Return the element for the given iterator;
|
||||
Uint32 get(iterator pos) const {return node[pos].element;}
|
||||
// Return one element of this set.
|
||||
Uint32 getOne() const {assert(count > 0); return node[0].element;}
|
||||
// Return the size of this set.
|
||||
Uint32 getSize() const {return count;}
|
||||
|
||||
#ifdef DEBUG_LOG
|
||||
// Print the set.
|
||||
void printPretty(LogModuleObject log);
|
||||
#endif // DEBUG_LOG
|
||||
};
|
||||
|
||||
inline void SparseSet::clear(Uint32 element)
|
||||
{
|
||||
checkMember(element);
|
||||
Uint32 count = this->count;
|
||||
Node* node = this->node;
|
||||
|
||||
Uint32 stackIndex = node[element].stackIndex;
|
||||
|
||||
if ((stackIndex < count) && (node[stackIndex].element == element)) {
|
||||
Uint32 stackTop = node[count - 1].element;
|
||||
|
||||
node[stackIndex].element = stackTop;
|
||||
node[stackTop].stackIndex = stackIndex;
|
||||
this->count = count - 1;
|
||||
}
|
||||
}
|
||||
|
||||
inline void SparseSet::set(Uint32 element)
|
||||
{
|
||||
checkMember(element);
|
||||
Uint32 count = this->count;
|
||||
Node* node = this->node;
|
||||
|
||||
Uint32 stackIndex = node[element].stackIndex;
|
||||
|
||||
if ((stackIndex >= count) || (node[stackIndex].element != element)) {
|
||||
node[count].element = element;
|
||||
node[element].stackIndex = count;
|
||||
this->count = count + 1;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool SparseSet::test(Uint32 element) const
|
||||
{
|
||||
checkMember(element);
|
||||
Node* node = this->node;
|
||||
|
||||
Uint32 stackIndex = node[element].stackIndex;
|
||||
return ((stackIndex < count) && (node[stackIndex].element == element));
|
||||
}
|
||||
|
||||
inline SparseSet& SparseSet::operator = (const SparseSet& set)
|
||||
{
|
||||
checkUniverseCompatibility(set);
|
||||
Uint32 sourceCount = set.getSize();
|
||||
Node* node = this->node;
|
||||
|
||||
memcpy(node, set.node, sourceCount * sizeof(Node));
|
||||
|
||||
for (Uint32 i = 0; i < sourceCount; i++) {
|
||||
Uint32 element = node[i].element;
|
||||
node[element].stackIndex = i;
|
||||
}
|
||||
|
||||
count = sourceCount;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
inline SparseSet& SparseSet::operator = (const BitSet& set)
|
||||
{
|
||||
// FIX: there's room for optimization here.
|
||||
assert(universeSize == set.getSize());
|
||||
|
||||
clear();
|
||||
for (Int32 i = set.firstOne(); i != -1; i = set.nextOne(i))
|
||||
this->set(i);
|
||||
return *this;
|
||||
}
|
||||
|
||||
#endif // _SPARSE_SET_H_
|
||||
270
mozilla/ef/Compiler/RegisterAllocator/Spilling.cpp
Normal file
270
mozilla/ef/Compiler/RegisterAllocator/Spilling.cpp
Normal file
@@ -0,0 +1,270 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef NEW_LAURENTM_CODE
|
||||
#define INCLUDE_EMITTER
|
||||
#include "CpuInfo.h"
|
||||
#include "Fundamentals.h"
|
||||
#include "ControlNodes.h"
|
||||
#include "Instruction.h"
|
||||
#include "InstructionEmitter.h"
|
||||
#include "Spilling.h"
|
||||
|
||||
|
||||
void Spilling::
|
||||
insertSpillCode(ControlNode** dfsList, Uint32 nNodes)
|
||||
{
|
||||
PRUint32 nVirtualRegisters = vRegManager.count();
|
||||
FastBitSet currentLive(vRegManager.pool, nVirtualRegisters);
|
||||
FastBitSet usedInThisInstruction(vRegManager.pool, nVirtualRegisters);
|
||||
RegisterFifo grNeedLoad(nVirtualRegisters);
|
||||
RegisterFifo fpNeedLoad(nVirtualRegisters);
|
||||
|
||||
for (PRInt32 n = nNodes - 1; n >= 0; n--)
|
||||
{
|
||||
PR_ASSERT(grNeedLoad.empty() & fpNeedLoad.empty());
|
||||
ControlNode& node = *dfsList[n];
|
||||
|
||||
currentLive = node.liveAtEnd;
|
||||
|
||||
PRUint32 nGeneralAlive = 0;
|
||||
PRUint32 nFloatingPointAlive = 0;
|
||||
|
||||
// Get the number of registers alive at the end of this node.
|
||||
for (PRInt32 j = currentLive.firstOne(); j != -1; j = currentLive.nextOne(j))
|
||||
{
|
||||
VirtualRegister& vReg = vRegManager.getVirtualRegister(j);
|
||||
if (vReg.spillInfo.willSpill)
|
||||
{
|
||||
currentLive.clear(j);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (vReg.getClass())
|
||||
{
|
||||
case vrcInteger:
|
||||
nGeneralAlive++;
|
||||
break;
|
||||
case vrcFloatingPoint:
|
||||
case vrcFixedPoint:
|
||||
nFloatingPointAlive++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if(node.dfsNum == 8) printf("\n________Begin Node %d________\n", node.dfsNum);
|
||||
|
||||
InstructionList& instructions = node.getInstructions();
|
||||
for (InstructionList::iterator i = instructions.end(); !instructions.done(i); i = instructions.retreat(i))
|
||||
{
|
||||
Instruction& instruction = instructions.get(i);
|
||||
InstructionUse* useBegin = instruction.getInstructionUseBegin();
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
InstructionUse* usePtr;
|
||||
InstructionDefine* defBegin = instruction.getInstructionDefineBegin();
|
||||
InstructionDefine* defEnd = instruction.getInstructionDefineEnd();
|
||||
InstructionDefine* defPtr;
|
||||
|
||||
// if(node.dfsNum == 8) { printf("\n");
|
||||
// instruction.printPretty(stdout);
|
||||
// printf("\n"); }
|
||||
|
||||
// Handle definitions
|
||||
for (defPtr = defBegin; defPtr < defEnd; defPtr++)
|
||||
if (defPtr->isVirtualRegister())
|
||||
{
|
||||
VirtualRegister& vReg = defPtr->getVirtualRegister();
|
||||
currentLive.clear(vReg.getRegisterIndex());
|
||||
switch (vReg.getClass())
|
||||
{
|
||||
case vrcInteger:
|
||||
nGeneralAlive--;
|
||||
break;
|
||||
case vrcFloatingPoint:
|
||||
case vrcFixedPoint:
|
||||
nFloatingPointAlive--;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for deaths
|
||||
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isVirtualRegister())
|
||||
{
|
||||
VirtualRegister& vReg = usePtr->getVirtualRegister();
|
||||
if (!currentLive.test(vReg.getRegisterIndex()))
|
||||
// This is the last use of this register.
|
||||
{
|
||||
currentLive.set(vReg.getRegisterIndex());
|
||||
switch (vReg.getClass())
|
||||
{
|
||||
case vrcInteger:
|
||||
nGeneralAlive++;
|
||||
while (/*(nGeneralAlive > NUMBER_OF_GREGISTERS) &&*/ !grNeedLoad.empty())
|
||||
{
|
||||
PRUint32 toLoad = grNeedLoad.get();
|
||||
currentLive.clear(toLoad);
|
||||
nGeneralAlive--;
|
||||
|
||||
VirtualRegister& nReg = vRegManager.getVirtualRegister(toLoad);
|
||||
Instruction& lastUsingInstruction = *nReg.spillInfo.lastUsingInstruction;
|
||||
emitter.emitLoadAfter(*lastUsingInstruction.getPrimitive(), lastUsingInstruction.getLinks().prev,
|
||||
nReg.getAlias(), *nReg.equivalentRegister[vrcStackSlot]);
|
||||
nReg.releaseSelf();
|
||||
}
|
||||
break;
|
||||
case vrcFloatingPoint:
|
||||
case vrcFixedPoint:
|
||||
nFloatingPointAlive++;
|
||||
while (/*(nFloatingPointAlive > NUMBER_OF_FPREGISTERS) &&*/ !fpNeedLoad.empty())
|
||||
{
|
||||
PRUint32 toLoad = fpNeedLoad.get();
|
||||
currentLive.clear(toLoad);
|
||||
nFloatingPointAlive--;
|
||||
|
||||
VirtualRegister& nReg = vRegManager.getVirtualRegister(toLoad);
|
||||
Instruction& lastUsingInstruction = *nReg.spillInfo.lastUsingInstruction;
|
||||
emitter.emitLoadAfter(*lastUsingInstruction.getPrimitive(), lastUsingInstruction.getLinks().prev,
|
||||
nReg.getAlias(), *nReg.equivalentRegister[vrcStackSlot]);
|
||||
nReg.releaseSelf();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle uses
|
||||
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isVirtualRegister())
|
||||
{
|
||||
VirtualRegister& vReg = usePtr->getVirtualRegister();
|
||||
PRUint32 registerIndex = vReg.getRegisterIndex();
|
||||
|
||||
if (vReg.spillInfo.willSpill) {
|
||||
#if defined(GENERATE_FOR_X86)
|
||||
if (!instruction.switchUseToSpill((usePtr - useBegin), *vReg.equivalentRegister[vrcStackSlot]))
|
||||
#endif
|
||||
{
|
||||
switch (vReg.getClass())
|
||||
{
|
||||
case vrcInteger:
|
||||
if (!grNeedLoad.test(registerIndex))
|
||||
{
|
||||
grNeedLoad.put(registerIndex);
|
||||
VirtualRegister& alias = vRegManager.newVirtualRegister(vrcInteger);
|
||||
if (vReg.isPreColored())
|
||||
alias.preColorRegister(vReg.getPreColor());
|
||||
/* if (vReg.hasSpecialInterference) {
|
||||
alias.specialInterference.sizeTo(NUMBER_OF_REGISTERS);
|
||||
alias.specialInterference = vReg.specialInterference;
|
||||
alias.hasSpecialInterference = true;
|
||||
} */
|
||||
vReg.setAlias(alias);
|
||||
vReg.retainSelf();
|
||||
}
|
||||
break;
|
||||
case vrcFloatingPoint:
|
||||
case vrcFixedPoint:
|
||||
if (!fpNeedLoad.test(registerIndex))
|
||||
{
|
||||
fpNeedLoad.put(registerIndex);
|
||||
VirtualRegister& alias = vRegManager.newVirtualRegister(vReg.getClass());
|
||||
if (vReg.isPreColored())
|
||||
alias.preColorRegister(vReg.getPreColor());
|
||||
/*if (vReg.hasSpecialInterference) {
|
||||
alias.specialInterference.sizeTo(NUMBER_OF_REGISTERS);
|
||||
alias.specialInterference = vReg.specialInterference;
|
||||
alias.hasSpecialInterference = true;
|
||||
} */
|
||||
vReg.setAlias(alias);
|
||||
vReg.retainSelf();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
usePtr->getVirtualRegisterPtr().initialize(vReg.getAlias());
|
||||
usedInThisInstruction.set(registerIndex);
|
||||
vReg.spillInfo.lastUsingInstruction = &instruction;
|
||||
}
|
||||
currentLive.clear(registerIndex);
|
||||
} else { // will not spill
|
||||
currentLive.set(registerIndex);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle definitions
|
||||
for (defPtr = defBegin; defPtr < defEnd; defPtr++)
|
||||
if (defPtr->isVirtualRegister())
|
||||
{
|
||||
VirtualRegister& vReg = defPtr->getVirtualRegister();
|
||||
|
||||
if (vReg.spillInfo.willSpill)
|
||||
#if defined(GENERATE_FOR_X86)
|
||||
if (!instruction.switchDefineToSpill((defPtr - defBegin), *vReg.equivalentRegister[vrcStackSlot]))
|
||||
#endif
|
||||
{
|
||||
if (usedInThisInstruction.test(vReg.getRegisterIndex()))
|
||||
// this virtualRegister was used in this instruction and is also defined. We need to move
|
||||
// this virtual register to its alias first and then save it to memory.
|
||||
{
|
||||
emitter.emitStoreAfter(*instruction.getPrimitive(), &instruction.getLinks(),
|
||||
vReg.getAlias(), *vReg.equivalentRegister[vrcStackSlot]);
|
||||
defPtr->getVirtualRegisterPtr().initialize(vReg.getAlias());
|
||||
}
|
||||
else
|
||||
{
|
||||
emitter.emitStoreAfter(*instruction.getPrimitive(), &instruction.getLinks(),
|
||||
vReg, *vReg.equivalentRegister[vrcStackSlot]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
while (!grNeedLoad.empty())
|
||||
{
|
||||
PRUint32 nl = grNeedLoad.get();
|
||||
VirtualRegister& nlReg = vRegManager.getVirtualRegister(nl);
|
||||
Instruction& lastUse = *nlReg.spillInfo.lastUsingInstruction;
|
||||
|
||||
emitter.emitLoadAfter(*lastUse.getPrimitive(), lastUse.getLinks().prev,
|
||||
nlReg.getAlias(), *nlReg.equivalentRegister[vrcStackSlot]);
|
||||
nlReg.releaseSelf();
|
||||
}
|
||||
while (!fpNeedLoad.empty())
|
||||
{
|
||||
PRUint32 nl = fpNeedLoad.get();
|
||||
VirtualRegister& nlReg = vRegManager.getVirtualRegister(nl);
|
||||
Instruction& lastUse = *nlReg.spillInfo.lastUsingInstruction;
|
||||
|
||||
emitter.emitLoadAfter(*lastUse.getPrimitive(), lastUse.getLinks().prev,
|
||||
nlReg.getAlias(), *nlReg.equivalentRegister[vrcStackSlot]);
|
||||
nlReg.releaseSelf();
|
||||
}
|
||||
|
||||
// if(node.dfsNum == 8) printf("\n________End Node %d________\n", node.dfsNum);
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
269
mozilla/ef/Compiler/RegisterAllocator/Spilling.h
Normal file
269
mozilla/ef/Compiler/RegisterAllocator/Spilling.h
Normal file
@@ -0,0 +1,269 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _SPILLING_H_
|
||||
#define _SPILLING_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include <string.h>
|
||||
#include "RegisterAllocator.h"
|
||||
#include "RegisterAllocatorTools.h"
|
||||
#include "ControlGraph.h"
|
||||
#include "ControlNodes.h"
|
||||
#include "Instruction.h"
|
||||
#include "SparseSet.h"
|
||||
|
||||
template <class RegisterPressure>
|
||||
class Spilling
|
||||
{
|
||||
private:
|
||||
static void insertStoreAfter(Instruction& instruction, RegisterName name);
|
||||
static void insertLoadBefore(Instruction& instruction, RegisterName name);
|
||||
|
||||
public:
|
||||
static void calculateSpillCosts(RegisterAllocator& registerAllocator);
|
||||
static void insertSpillCode(RegisterAllocator& registerAllocator);
|
||||
};
|
||||
|
||||
struct SpillCost
|
||||
{
|
||||
double loads;
|
||||
double stores;
|
||||
double copies;
|
||||
double cost;
|
||||
bool infinite;
|
||||
};
|
||||
|
||||
template <class RegisterPressure>
|
||||
void Spilling<RegisterPressure>::insertSpillCode(RegisterAllocator& registerAllocator)
|
||||
{
|
||||
Uint32 rangeCount = registerAllocator.rangeCount;
|
||||
RegisterName* name2range = registerAllocator.name2range;
|
||||
|
||||
Pool& pool = registerAllocator.pool;
|
||||
SparseSet currentLive(pool, rangeCount);
|
||||
SparseSet needLoad(pool, rangeCount);
|
||||
SparseSet mustSpill(pool, rangeCount);
|
||||
SparseSet& willSpill = *registerAllocator.willSpill;
|
||||
|
||||
ControlGraph& controlGraph = registerAllocator.controlGraph;
|
||||
RegisterPressure::Set* liveOut = registerAllocator.liveness.liveOut;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
|
||||
needLoad.clear();
|
||||
currentLive = liveOut[n];
|
||||
mustSpill = currentLive;
|
||||
|
||||
InstructionList& instructions = nodes[n]->getInstructions();
|
||||
for (InstructionList::iterator i = instructions.end(); !instructions.done(i);) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
i = instructions.retreat(i);
|
||||
|
||||
InstructionUse* useBegin = instruction.getInstructionUseBegin();
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
InstructionUse* usePtr;
|
||||
InstructionDefine* defineBegin = instruction.getInstructionDefineBegin();
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
InstructionDefine* definePtr;
|
||||
|
||||
bool foundLiveDefine = false;
|
||||
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister()) {
|
||||
if (currentLive.test(name2range[definePtr->getRegisterName()])) {
|
||||
foundLiveDefine = true;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
foundLiveDefine = true;
|
||||
break;
|
||||
}
|
||||
if (defineBegin != defineEnd && !foundLiveDefine) {
|
||||
fprintf(stderr, "!!! Removed instruction because it was only defining unused registers !!!\n");
|
||||
instruction.remove();
|
||||
}
|
||||
|
||||
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister()) {
|
||||
RegisterName range = name2range[definePtr->getRegisterName()];
|
||||
#ifdef DEBUG
|
||||
if (needLoad.test(range))
|
||||
if (!mustSpill.test(range) && registerAllocator.spillCost[range].infinite && willSpill.test(range)) {
|
||||
fprintf(stderr, "Tried to spill a register with infinite spill cost\n");
|
||||
abort();
|
||||
}
|
||||
#endif // DEBUG
|
||||
if (willSpill.test(range))
|
||||
insertStoreAfter(instruction, range);
|
||||
|
||||
needLoad.clear(range);
|
||||
}
|
||||
|
||||
if (instruction.getFlags() & ifCopy)
|
||||
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister()) {
|
||||
RegisterName range = name2range[usePtr->getRegisterName()];
|
||||
if (!currentLive.test(range))
|
||||
for (SparseSet::iterator r = needLoad.begin(); !needLoad.done(r); r = needLoad.advance(r)) {
|
||||
RegisterName load = RegisterName(needLoad.get(r));
|
||||
if (willSpill.test(load))
|
||||
insertLoadBefore(instruction, load);
|
||||
mustSpill.set(load);
|
||||
}
|
||||
needLoad.clear();
|
||||
}
|
||||
|
||||
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister())
|
||||
currentLive.clear(name2range[definePtr->getRegisterName()]);
|
||||
|
||||
|
||||
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister()) {
|
||||
RegisterName range = name2range[usePtr->getRegisterName()];
|
||||
currentLive.set(range);
|
||||
needLoad.set(range);
|
||||
}
|
||||
}
|
||||
|
||||
for (SparseSet::iterator l = needLoad.begin(); !needLoad.done(l); l = needLoad.advance(l)) {
|
||||
RegisterName load = RegisterName(needLoad.get(l));
|
||||
if (willSpill.test(load))
|
||||
insertLoadBefore(instructions.first(), load);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
void Spilling<RegisterPressure>::insertLoadBefore(Instruction& /*instruction*/, RegisterName name)
|
||||
{
|
||||
fprintf(stdout, "will insert load for range %d\n", name);
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
void Spilling<RegisterPressure>::insertStoreAfter(Instruction& /*instruction*/, RegisterName name)
|
||||
{
|
||||
fprintf(stdout, "will insert store for range %d\n", name);
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
void Spilling<RegisterPressure>::calculateSpillCosts(RegisterAllocator& registerAllocator)
|
||||
{
|
||||
Uint32 rangeCount = registerAllocator.rangeCount;
|
||||
RegisterName* name2range = registerAllocator.name2range;
|
||||
|
||||
Pool& pool = registerAllocator.pool;
|
||||
SparseSet live(pool, rangeCount);
|
||||
SparseSet needLoad(pool, rangeCount);
|
||||
SparseSet mustSpill(pool, rangeCount);
|
||||
|
||||
SparseSet alreadyStored(pool, rangeCount); // FIX: should get this from previous spilling.
|
||||
|
||||
SpillCost* cost = new SpillCost[rangeCount];
|
||||
memset(cost, '\0', rangeCount * sizeof(SpillCost));
|
||||
|
||||
ControlGraph& controlGraph = registerAllocator.controlGraph;
|
||||
RegisterPressure::Set* liveOut = registerAllocator.liveness.liveOut;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
ControlNode& node = *nodes[n];
|
||||
|
||||
double weight = doLog10(node.loopDepth);
|
||||
|
||||
needLoad.clear();
|
||||
live = liveOut[n];
|
||||
mustSpill = live;
|
||||
|
||||
InstructionList& instructions = nodes[n]->getInstructions();
|
||||
for (InstructionList::iterator i = instructions.end(); !instructions.done(i); i = instructions.retreat(i)) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
|
||||
InstructionUse* useBegin = instruction.getInstructionUseBegin();
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
InstructionUse* usePtr;
|
||||
InstructionDefine* defineBegin = instruction.getInstructionDefineBegin();
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
InstructionDefine* definePtr;
|
||||
|
||||
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister()) {
|
||||
RegisterName range = name2range[definePtr->getRegisterName()];
|
||||
|
||||
if (needLoad.test(range))
|
||||
if (!mustSpill.test(range))
|
||||
cost[range].infinite = true;
|
||||
|
||||
if ((false /* !rematerializable(range) */ || !needLoad.test(range)) && !alreadyStored.test(range))
|
||||
cost[range].stores += weight;
|
||||
|
||||
needLoad.clear(range);
|
||||
}
|
||||
|
||||
if (instruction.getFlags() & ifCopy)
|
||||
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister())
|
||||
if (!live.test(name2range[usePtr->getRegisterName()])) {
|
||||
for (SparseSet::iterator l = needLoad.begin(); !needLoad.done(l); l = needLoad.advance(l)) {
|
||||
Uint32 range = needLoad.get(l);
|
||||
cost[range].loads += weight;
|
||||
mustSpill.set(range);
|
||||
}
|
||||
needLoad.clear();
|
||||
}
|
||||
|
||||
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister())
|
||||
live.clear(name2range[definePtr->getRegisterName()]);
|
||||
|
||||
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister()) {
|
||||
RegisterName range = name2range[usePtr->getRegisterName()];
|
||||
|
||||
live.set(range);
|
||||
needLoad.set(range);
|
||||
}
|
||||
|
||||
if (instruction.getFlags() & ifCopy) {
|
||||
assert(useBegin != useEnd && useBegin[0].isRegister());
|
||||
assert(defineBegin != defineEnd && defineBegin[0].isRegister());
|
||||
|
||||
RegisterName source = name2range[useBegin[0].getRegisterName()];
|
||||
RegisterName destination = name2range[defineBegin[0].getRegisterName()];
|
||||
|
||||
cost[source].copies += weight;
|
||||
cost[destination].copies += weight;
|
||||
}
|
||||
}
|
||||
|
||||
for (SparseSet::iterator s = needLoad.begin(); !needLoad.done(s); s = needLoad.advance(s))
|
||||
cost[needLoad.get(s)].loads += weight;
|
||||
}
|
||||
|
||||
for (Uint32 r = 0; r < rangeCount; r++) {
|
||||
SpillCost& c = cost[r];
|
||||
c.cost = 2 * (c.loads + c.stores) - c.copies;
|
||||
}
|
||||
|
||||
registerAllocator.spillCost = cost;
|
||||
}
|
||||
|
||||
#endif // _SPILLING_H_
|
||||
239
mozilla/ef/Compiler/RegisterAllocator/Splits.h
Normal file
239
mozilla/ef/Compiler/RegisterAllocator/Splits.h
Normal file
@@ -0,0 +1,239 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _SPLITS_H_
|
||||
#define _SPLITS_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include <string.h>
|
||||
#include "Pool.h"
|
||||
#include "ControlGraph.h"
|
||||
#include "ControlNodes.h"
|
||||
#include "Instruction.h"
|
||||
#include "RegisterAllocator.h"
|
||||
#include "RegisterAllocatorTools.h"
|
||||
|
||||
UT_EXTERN_LOG_MODULE(RegAlloc);
|
||||
|
||||
template <class RegisterPressure>
|
||||
struct Splits
|
||||
{
|
||||
static void calculateSplitCosts(RegisterAllocator& registerAllocator);
|
||||
static bool findSplit(RegisterAllocator& registerAllocator, RegisterName* color, RegisterName range);
|
||||
static void insertSplitCode(RegisterAllocator& registerAllocator);
|
||||
};
|
||||
|
||||
struct SplitCost
|
||||
{
|
||||
double loads;
|
||||
double stores;
|
||||
};
|
||||
|
||||
template <class RegisterPressure>
|
||||
void Splits<RegisterPressure>::insertSplitCode(RegisterAllocator& /*registerAllocator*/)
|
||||
{
|
||||
// FIX
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
bool Splits<RegisterPressure>::findSplit(RegisterAllocator& registerAllocator, RegisterName* color, RegisterName range)
|
||||
{
|
||||
Pool& pool = registerAllocator.pool;
|
||||
NameLinkedList** neighborsWithColor = new(pool) NameLinkedList*[6]; // FIX
|
||||
memset(neighborsWithColor, '\0', 6 * sizeof(NameLinkedList*));
|
||||
|
||||
InterferenceGraph<RegisterPressure>& iGraph = registerAllocator.iGraph;
|
||||
|
||||
for (InterferenceVector* vector = iGraph.getInterferenceVector(range); vector != NULL; vector = vector->next)
|
||||
for (Int32 i = vector->count - 1; i >=0; --i) {
|
||||
RegisterName neighbor = vector->neighbors[i];
|
||||
RegisterName c = color[neighbor];
|
||||
|
||||
if (c < 6) { // FIX
|
||||
NameLinkedList* node = new(pool) NameLinkedList();
|
||||
node->name = neighbor;
|
||||
node->next = neighborsWithColor[c];
|
||||
neighborsWithColor[c] = node;
|
||||
}
|
||||
}
|
||||
|
||||
bool splitAroundName = true;
|
||||
|
||||
LiveRangeGraph<RegisterPressure>& lGraph = registerAllocator.lGraph;
|
||||
RegisterName bestColor = RegisterName(6); // FIX
|
||||
double bestCost = registerAllocator.spillCost[range].cost;
|
||||
SplitCost* splitCost = registerAllocator.splitCost;
|
||||
|
||||
for (RegisterName i = RegisterName(0); i < 6; i = RegisterName(i + 1)) { // FIX
|
||||
|
||||
double splitAroundNameCost = 0.0;
|
||||
bool canSplitAroundName = true;
|
||||
|
||||
SplitCost& sCost = splitCost[range];
|
||||
double addedCost = 2.0 * (sCost.stores + sCost.loads);
|
||||
|
||||
for (NameLinkedList* node = neighborsWithColor[i]; node != NULL; node = node->next) {
|
||||
RegisterName neighbor = node->name;
|
||||
if (lGraph.haveEdge(neighbor, range)) {
|
||||
canSplitAroundName = false;
|
||||
break;
|
||||
} else
|
||||
splitAroundNameCost += addedCost;
|
||||
}
|
||||
if (canSplitAroundName && splitAroundNameCost < bestCost) {
|
||||
bestCost = splitAroundNameCost;
|
||||
bestColor = i;
|
||||
splitAroundName = true;
|
||||
}
|
||||
|
||||
double splitAroundColorCost = 0.0;
|
||||
bool canSplitAroundColor = true;
|
||||
|
||||
for (NameLinkedList* node = neighborsWithColor[i]; node != NULL; node = node->next) {
|
||||
RegisterName neighbor = node->name;
|
||||
if (lGraph.haveEdge(range, neighbor)) {
|
||||
canSplitAroundColor = false;
|
||||
break;
|
||||
} else {
|
||||
SplitCost& sCost = splitCost[neighbor];
|
||||
double addedCost = 2.0 * (sCost.stores + sCost.loads);
|
||||
splitAroundColorCost += addedCost;
|
||||
}
|
||||
}
|
||||
if (canSplitAroundColor && splitAroundColorCost < bestCost) {
|
||||
bestCost = splitAroundColorCost;
|
||||
bestColor = i;
|
||||
splitAroundName = false;
|
||||
}
|
||||
}
|
||||
if (bestColor < RegisterName(6)) {
|
||||
color[range] = bestColor;
|
||||
registerAllocator.splitFound = true;
|
||||
|
||||
NameLinkedList** splitAround = registerAllocator.splitAround;
|
||||
|
||||
if (splitAroundName)
|
||||
for (NameLinkedList* node = neighborsWithColor[bestColor]; node != NULL; node = node->next) {
|
||||
NameLinkedList* newNode = new(pool) NameLinkedList();
|
||||
newNode->name = node->name;
|
||||
newNode->next = splitAround[range];
|
||||
splitAround[range] = newNode;
|
||||
}
|
||||
else
|
||||
for (NameLinkedList* node = neighborsWithColor[bestColor]; node != NULL; node = node->next) {
|
||||
NameLinkedList* newNode = new(pool) NameLinkedList();
|
||||
RegisterName neighbor = node->name;
|
||||
newNode->name = range;
|
||||
newNode->next = splitAround[neighbor];
|
||||
splitAround[neighbor] = newNode;
|
||||
}
|
||||
|
||||
trespass("Found a split");
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template <class RegisterPressure>
|
||||
void Splits<RegisterPressure>::calculateSplitCosts(RegisterAllocator& registerAllocator)
|
||||
{
|
||||
Pool& pool = registerAllocator.pool;
|
||||
Uint32 rangeCount = registerAllocator.rangeCount;
|
||||
RegisterName* name2range = registerAllocator.name2range;
|
||||
|
||||
SplitCost* splitCost = new(pool) SplitCost[rangeCount];
|
||||
memset(splitCost, '\0', rangeCount * sizeof(SplitCost));
|
||||
|
||||
SparseSet live(pool, rangeCount);
|
||||
RegisterPressure::Set* liveIn = registerAllocator.liveness.liveIn;
|
||||
RegisterPressure::Set* liveOut = registerAllocator.liveness.liveOut;
|
||||
|
||||
ControlGraph& controlGraph = registerAllocator.controlGraph;
|
||||
ControlNode** nodes = controlGraph.dfsList;
|
||||
Uint32 nNodes = controlGraph.nNodes;
|
||||
|
||||
for (Uint32 n = 0; n < nNodes; n++) {
|
||||
ControlNode& node = *nodes[n];
|
||||
double weight = doLog10(node.loopDepth);
|
||||
|
||||
live = liveOut[n];
|
||||
|
||||
ControlEdge* successorsEnd = node.getSuccessorsEnd();
|
||||
for (ControlEdge* successorsPtr = node.getSuccessorsBegin(); successorsPtr < successorsEnd; successorsPtr++) {
|
||||
ControlNode& successor = successorsPtr->getTarget();
|
||||
|
||||
if (successor.getControlKind() != ckEnd) {
|
||||
RegisterPressure::Set& successorLiveIn = liveIn[successor.dfsNum];
|
||||
|
||||
for (SparseSet::iterator i = live.begin(); !live.done(i); i = live.advance(i)) {
|
||||
RegisterName name = RegisterName(live.get(i));
|
||||
if (!successorLiveIn.test(name))
|
||||
splitCost[name].loads += doLog10(successor.loopDepth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
InstructionList& instructions = node.getInstructions();
|
||||
for (InstructionList::iterator i = instructions.end(); !instructions.done(i); i = instructions.retreat(i)) {
|
||||
Instruction& instruction = instructions.get(i);
|
||||
|
||||
InstructionUse* useBegin = instruction.getInstructionUseBegin();
|
||||
InstructionUse* useEnd = instruction.getInstructionUseEnd();
|
||||
InstructionUse* usePtr;
|
||||
InstructionDefine* defineBegin = instruction.getInstructionDefineBegin();
|
||||
InstructionDefine* defineEnd = instruction.getInstructionDefineEnd();
|
||||
InstructionDefine* definePtr;
|
||||
|
||||
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister())
|
||||
splitCost[name2range[definePtr->getRegisterName()]].stores += weight;
|
||||
|
||||
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister()) {
|
||||
RegisterName range = name2range[usePtr->getRegisterName()];
|
||||
if (!live.test(range)) {
|
||||
if (&instruction != &instructions.last())
|
||||
splitCost[range].loads += weight;
|
||||
else {
|
||||
ControlEdge* successorsEnd = node.getSuccessorsEnd();
|
||||
for (ControlEdge* successorsPtr = node.getSuccessorsBegin(); successorsPtr < successorsEnd; successorsPtr++)
|
||||
splitCost[range].loads += doLog10(successorsPtr->getTarget().loopDepth);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (definePtr = defineBegin; definePtr < defineEnd; definePtr++)
|
||||
if (definePtr->isRegister())
|
||||
live.clear(name2range[definePtr->getRegisterName()]);
|
||||
|
||||
for (usePtr = useBegin; usePtr < useEnd; usePtr++)
|
||||
if (usePtr->isRegister())
|
||||
live.set(name2range[usePtr->getRegisterName()]);
|
||||
}
|
||||
}
|
||||
|
||||
NameLinkedList** splitAround = new(pool) NameLinkedList*[rangeCount];
|
||||
memset(splitAround, '\0', rangeCount * sizeof(NameLinkedList*));
|
||||
registerAllocator.splitAround = splitAround;
|
||||
|
||||
registerAllocator.splitCost = splitCost;
|
||||
registerAllocator.splitFound = false;
|
||||
}
|
||||
|
||||
#endif // _SPLITS_H_
|
||||
186
mozilla/ef/Compiler/RegisterAllocator/Timer.cpp
Normal file
186
mozilla/ef/Compiler/RegisterAllocator/Timer.cpp
Normal file
@@ -0,0 +1,186 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "HashTable.h"
|
||||
#include "Timer.h"
|
||||
#include "Pool.h"
|
||||
|
||||
static Pool pool; // Pool for the Timer class.
|
||||
static HashTable<TimerEntry*> timerEntries(pool); // Timers hashtable.
|
||||
|
||||
const nTimersInABlock = 128; // Number of timers in a block.
|
||||
static PRTime *timers = new(pool) PRTime[nTimersInABlock]; // A block of timers.
|
||||
static Uint8 nextTimer = 0; // nextAvailableTimer.
|
||||
|
||||
//
|
||||
// Calibrate the call to PR_Now().
|
||||
//
|
||||
static PRTime calibrate()
|
||||
{
|
||||
PRTime t = PR_Now();
|
||||
PRTime& a = *new(pool) PRTime();
|
||||
|
||||
// Call 10 times the PR_Now() function.
|
||||
a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now();
|
||||
a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now(); a = PR_Now();
|
||||
t = (PR_Now() - t + 9) / 10;
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
static PRTime adjust = calibrate();
|
||||
|
||||
//
|
||||
// Return the named timer..
|
||||
//
|
||||
TimerEntry& Timer::getTimerEntry(const char* name)
|
||||
{
|
||||
if (!timerEntries.exists(name)) {
|
||||
TimerEntry* newEntry = new(pool) TimerEntry();
|
||||
newEntry->accumulator = 0;
|
||||
newEntry->running = false;
|
||||
timerEntries.add(name, newEntry);
|
||||
}
|
||||
|
||||
return *timerEntries[name];
|
||||
}
|
||||
|
||||
//
|
||||
// Return a reference to a new timer.
|
||||
//
|
||||
PRTime& Timer::getNewTimer()
|
||||
{
|
||||
if (nextTimer >= nTimersInABlock) {
|
||||
timers = new(pool) PRTime[nTimersInABlock];
|
||||
nextTimer = 0;
|
||||
}
|
||||
return timers[nextTimer++];
|
||||
}
|
||||
|
||||
static Uint32 timersAreFrozen = 0;
|
||||
|
||||
//
|
||||
// Start the named timer.
|
||||
//
|
||||
void Timer::start(const char* name)
|
||||
{
|
||||
if (timersAreFrozen)
|
||||
return;
|
||||
|
||||
freezeTimers();
|
||||
|
||||
TimerEntry& timer = getTimerEntry(name);
|
||||
PR_ASSERT(!timer.running);
|
||||
|
||||
timer.accumulator = 0;
|
||||
timer.running = true;
|
||||
timer.done = false;
|
||||
|
||||
unfreezeTimers();
|
||||
}
|
||||
|
||||
//
|
||||
// Stop the named timer.
|
||||
//
|
||||
void Timer::stop(const char* name)
|
||||
{
|
||||
if (timersAreFrozen)
|
||||
return;
|
||||
|
||||
freezeTimers();
|
||||
|
||||
TimerEntry& timer = getTimerEntry(name);
|
||||
PR_ASSERT(timer.running);
|
||||
timer.running = false;
|
||||
timer.done = true;
|
||||
|
||||
unfreezeTimers();
|
||||
}
|
||||
|
||||
//
|
||||
// Freeze all the running timers.
|
||||
//
|
||||
void Timer::freezeTimers()
|
||||
{
|
||||
PRTime when = PR_Now() - adjust;
|
||||
|
||||
if (timersAreFrozen == 0) {
|
||||
Vector<TimerEntry*> entries = timerEntries;
|
||||
Uint32 count = entries.size();
|
||||
|
||||
for (Uint32 i = 0; i < count; i++) {
|
||||
TimerEntry& entry = *entries[i];
|
||||
if (entry.running) {
|
||||
entry.accumulator += (when - *entry.startTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
timersAreFrozen++;
|
||||
}
|
||||
|
||||
//
|
||||
// Unfreeze all the running timers.
|
||||
//
|
||||
void Timer::unfreezeTimers()
|
||||
{
|
||||
PR_ASSERT(timersAreFrozen != 0);
|
||||
timersAreFrozen--;
|
||||
|
||||
if (timersAreFrozen == 0) {
|
||||
Vector<TimerEntry *> entries = timerEntries;
|
||||
Uint32 count = entries.size();
|
||||
|
||||
PRTime& newStart = getNewTimer();
|
||||
|
||||
for (Uint32 i = 0; i < count; i++) {
|
||||
TimerEntry& entry = *entries[i];
|
||||
if (entry.running) {
|
||||
entry.startTime = &newStart;
|
||||
}
|
||||
}
|
||||
|
||||
newStart = PR_Now();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Print the named timer in the file f.
|
||||
//
|
||||
void Timer::print(FILE* f, const char *name)
|
||||
{
|
||||
if (timersAreFrozen)
|
||||
return;
|
||||
|
||||
freezeTimers();
|
||||
|
||||
TimerEntry& timer = getTimerEntry(name);
|
||||
|
||||
PR_ASSERT(timer.done);
|
||||
PRTime elapsed = timer.accumulator;
|
||||
|
||||
if (elapsed >> 32) {
|
||||
fprintf(f, "[timer %s out of range]\n", name);
|
||||
} else {
|
||||
fprintf(f, "[%dus in %s]\n", Uint32(elapsed), name);
|
||||
}
|
||||
fflush(f);
|
||||
|
||||
unfreezeTimers();
|
||||
}
|
||||
|
||||
80
mozilla/ef/Compiler/RegisterAllocator/Timer.h
Normal file
80
mozilla/ef/Compiler/RegisterAllocator/Timer.h
Normal file
@@ -0,0 +1,80 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _TIMER_H_
|
||||
#define _TIMER_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "HashTable.h"
|
||||
#include "prtime.h"
|
||||
|
||||
//
|
||||
// Naming convention:
|
||||
// As the class Timer contains only static methods, the timer's name should start with the
|
||||
// module name. Otherwise starting 2 timers with the same name will assert.
|
||||
//
|
||||
|
||||
#ifndef NO_TIMER
|
||||
|
||||
struct TimerEntry
|
||||
{
|
||||
PRTime *startTime; // Current time when we start the timer.
|
||||
PRTime accumulator; // Time spent in this timer.
|
||||
bool running; // True if the timer is running.
|
||||
bool done; // True if the timer was running and was stopped.
|
||||
};
|
||||
|
||||
class Timer
|
||||
{
|
||||
private:
|
||||
|
||||
// Return the named timer.
|
||||
static TimerEntry& getTimerEntry(const char* name);
|
||||
// Return a reference to a new Timer.
|
||||
static PRTime& getNewTimer();
|
||||
|
||||
public:
|
||||
|
||||
// Start the timer.
|
||||
static void start(const char* name);
|
||||
// Stop the timer.
|
||||
static void stop(const char* name);
|
||||
// Freeze all the running timers.
|
||||
static void freezeTimers();
|
||||
// Unfreeze all the running timers.
|
||||
static void unfreezeTimers();
|
||||
// Print the timer.
|
||||
static void print(FILE* f, const char *name);
|
||||
};
|
||||
|
||||
inline void startTimer(const char* name) {Timer::start(name);}
|
||||
inline void stopTimer(const char* name) {Timer::stop(name); Timer::print(stdout, name);}
|
||||
#define START_TIMER_SAFE Timer::freezeTimers();
|
||||
#define END_TIMER_SAFE Timer::unfreezeTimers();
|
||||
#define TIMER_SAFE(x) START_TIMER_SAFE x; END_TIMER_SAFE
|
||||
|
||||
#else /* NO_TIMER */
|
||||
|
||||
inline void startTimer(const char* /*name*/) {}
|
||||
inline void stopTimer(const char* /*name*/) {}
|
||||
#define START_TIMER_SAFE
|
||||
#define END_TIMER_SAFE
|
||||
#define TIMER_SAFE(x) x;
|
||||
|
||||
#endif /* NO_TIMER */
|
||||
#endif /* _TIMER_H_ */
|
||||
40
mozilla/ef/Compiler/RegisterAllocator/VirtualRegister.cpp
Normal file
40
mozilla/ef/Compiler/RegisterAllocator/VirtualRegister.cpp
Normal file
@@ -0,0 +1,40 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "VirtualRegister.h"
|
||||
#include "Instruction.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// VirtualRegister -
|
||||
|
||||
#ifdef MANUAL_TEMPLATES
|
||||
template class IndexedPool<VirtualRegister>;
|
||||
#endif
|
||||
|
||||
// Set the defining instruction.
|
||||
//
|
||||
void VirtualRegister::setDefiningInstruction(Instruction& instruction)
|
||||
{
|
||||
if (definingInstruction != NULL) {
|
||||
if ((instruction.getFlags() & ifCopy) && (definingInstruction->getFlags() & ifPhiNode))
|
||||
return;
|
||||
}
|
||||
definingInstruction = &instruction;
|
||||
}
|
||||
|
||||
116
mozilla/ef/Compiler/RegisterAllocator/VirtualRegister.h
Normal file
116
mozilla/ef/Compiler/RegisterAllocator/VirtualRegister.h
Normal file
@@ -0,0 +1,116 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _VIRTUAL_REGISTER_H_
|
||||
#define _VIRTUAL_REGISTER_H_
|
||||
|
||||
#include "Fundamentals.h"
|
||||
#include "IndexedPool.h"
|
||||
#include <string.h>
|
||||
|
||||
#include "RegisterTypes.h"
|
||||
#include "RegisterClass.h"
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// VirtualRegister - 24b
|
||||
|
||||
class Instruction;
|
||||
|
||||
class VirtualRegister : public IndexedObject<VirtualRegister>
|
||||
{
|
||||
public:
|
||||
|
||||
Instruction* definingInstruction; // Instruction defining this VR.
|
||||
|
||||
// Initialize a VR of the given classKind.
|
||||
VirtualRegister(RegisterClassKind /*classKind*/) : definingInstruction(NULL) {}
|
||||
|
||||
// Return the defining instruction for this VR.
|
||||
Instruction* getDefiningInstruction() const {return definingInstruction;}
|
||||
// Set the defining instruction.
|
||||
void setDefiningInstruction(Instruction& insn);
|
||||
};
|
||||
|
||||
// Return true if the VirtualRegisters are equals. The only way 2 VRs can be equal is if
|
||||
// they have the same index. If they have the same index then they are at the same
|
||||
// address in the indexed pool.
|
||||
//
|
||||
inline bool operator == (const VirtualRegister& regA, const VirtualRegister& regB) {return ®A == ®B;}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// VirtualRegisterManager -
|
||||
|
||||
struct PreColoredRegister
|
||||
{
|
||||
RegisterID id;
|
||||
RegisterName color;
|
||||
};
|
||||
|
||||
class VirtualRegisterManager
|
||||
{
|
||||
private:
|
||||
|
||||
IndexedPool<VirtualRegister> registerPool;
|
||||
PreColoredRegister machineRegister[6];
|
||||
|
||||
public:
|
||||
VirtualRegisterManager()
|
||||
{
|
||||
for (Uint32 i = 0; i < 6; i++)
|
||||
machineRegister[i].id = invalidID;
|
||||
}
|
||||
|
||||
// Return the VirtualRegister at the given index.
|
||||
VirtualRegister& getVirtualRegister(RegisterName name) const {return registerPool.get(name);}
|
||||
|
||||
// Return a new VirtualRegister.
|
||||
RegisterID newVirtualRegister(RegisterClassKind classKind)
|
||||
{
|
||||
VirtualRegister& vReg = *new(registerPool) VirtualRegister(classKind);
|
||||
RegisterID rid;
|
||||
|
||||
setName(rid, RegisterName(vReg.getIndex()));
|
||||
setClass(rid, classKind);
|
||||
return rid;
|
||||
}
|
||||
|
||||
RegisterID newMachineRegister(RegisterName name, RegisterClassKind classKind)
|
||||
{
|
||||
RegisterID rid = machineRegister[name].id;
|
||||
|
||||
if (rid == invalidID) {
|
||||
rid = newVirtualRegister(classKind);
|
||||
DEBUG_ONLY(setMachineRegister(rid));
|
||||
machineRegister[name].id = rid;
|
||||
machineRegister[name].color = name;
|
||||
}
|
||||
|
||||
return rid;
|
||||
}
|
||||
|
||||
PreColoredRegister* getMachineRegistersBegin() const {return (PreColoredRegister*) machineRegister;} // FIX
|
||||
PreColoredRegister* getMachineRegistersEnd() const {return (PreColoredRegister*) &machineRegister[6];} // FIX
|
||||
|
||||
// Return the VirtualRegister universe size.
|
||||
Uint32 getSize() {return registerPool.getSize();}
|
||||
|
||||
void setSize(Uint32 size) {registerPool.setSize(size);}
|
||||
};
|
||||
|
||||
#endif // _VIRTUAL_REGISTER_H_
|
||||
@@ -1,5 +0,0 @@
|
||||
<IfModule mod_rewrite.c>
|
||||
RewriteEngine on
|
||||
RewriteRule ^$ webroot/ [L]
|
||||
RewriteRule (.*) webroot/$1 [L]
|
||||
</IfModule>
|
||||
@@ -1,25 +0,0 @@
|
||||
SERVER REQUIREMENTS
|
||||
- Apache 1.3 or higher with mod_rewrite enabled
|
||||
- PHP 4.3.2 or higher
|
||||
- CakePHP 1.1.7.3363 or higher
|
||||
- MySQL (preferred) or PostgreSQL
|
||||
|
||||
INSTALLATION:
|
||||
- All files accompanying this README should be placed into the /app directory of
|
||||
your CakePHP install. Once complete, you should have a directory structure similar
|
||||
to the following where (/) is the base of your domain:
|
||||
/
|
||||
app/
|
||||
config/
|
||||
controllers/
|
||||
models/
|
||||
webroot/
|
||||
...
|
||||
cake/
|
||||
vendors/
|
||||
|
||||
- Import the database schema (/app/config/dist.sql) into your database
|
||||
- Rename database.dist.php to database.php and edit the file to reflect your
|
||||
database configuration
|
||||
- Rename bootstrap.dist.php to bootstrap.php and follow the editing instructions
|
||||
within. All fields except APP_* and MAX_YEAR are optional.
|
||||
@@ -1,4 +0,0 @@
|
||||
<?php
|
||||
class AppController extends Controller {
|
||||
}
|
||||
?>
|
||||
@@ -1,4 +0,0 @@
|
||||
<?php
|
||||
class AppModel extends Model {
|
||||
}
|
||||
?>
|
||||
@@ -1,76 +0,0 @@
|
||||
;<?php die() ?>
|
||||
; SVN FILE: $Id: acl.ini.php,v 1.3 2006-10-08 03:39:21 reed%reedloden.com Exp $
|
||||
;/**
|
||||
; * Short description for file.
|
||||
; *
|
||||
; *
|
||||
; * PHP versions 4 and 5
|
||||
; *
|
||||
; * CakePHP : Rapid Development Framework <http://www.cakephp.org/>
|
||||
; * Copyright (c) 2006, Cake Software Foundation, Inc.
|
||||
; * 1785 E. Sahara Avenue, Suite 490-204
|
||||
; * Las Vegas, Nevada 89104
|
||||
; *
|
||||
; * Licensed under The MIT License
|
||||
; * Redistributions of files must retain the above copyright notice.
|
||||
; *
|
||||
; * @filesource
|
||||
; * @copyright Copyright (c) 2006, Cake Software Foundation, Inc.
|
||||
; * @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
|
||||
; * @package cake
|
||||
; * @subpackage cake.app.config
|
||||
; * @since CakePHP v 0.10.0.1076
|
||||
; * @version $Revision: 1.3 $
|
||||
; * @modifiedby $LastChangedBy: phpnut $
|
||||
; * @lastmodified $Date: 2006-10-08 03:39:21 $
|
||||
; * @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
||||
; */
|
||||
|
||||
; acl.ini.php - Cake ACL Configuration
|
||||
; ---------------------------------------------------------------------
|
||||
; Use this file to specify user permissions.
|
||||
; aco = access control object (something in your application)
|
||||
; aro = access request object (something requesting access)
|
||||
;
|
||||
; User records are added as follows:
|
||||
;
|
||||
; [uid]
|
||||
; groups = group1, group2, group3
|
||||
; allow = aco1, aco2, aco3
|
||||
; deny = aco4, aco5, aco6
|
||||
;
|
||||
; Group records are added in a similar manner:
|
||||
;
|
||||
; [gid]
|
||||
; allow = aco1, aco2, aco3
|
||||
; deny = aco4, aco5, aco6
|
||||
;
|
||||
; The allow, deny, and groups sections are all optional.
|
||||
; NOTE: groups names *cannot* ever be the same as usernames!
|
||||
;
|
||||
; ACL permissions are checked in the following order:
|
||||
; 1. Check for user denies (and DENY if specified)
|
||||
; 2. Check for user allows (and ALLOW if specified)
|
||||
; 3. Gather user's groups
|
||||
; 4. Check group denies (and DENY if specified)
|
||||
; 5. Check group allows (and ALLOW if specified)
|
||||
; 6. If no aro, aco, or group information is found, DENY
|
||||
;
|
||||
; ---------------------------------------------------------------------
|
||||
|
||||
;-------------------------------------
|
||||
;Users
|
||||
;-------------------------------------
|
||||
|
||||
[username-goes-here]
|
||||
groups = group1, group2
|
||||
deny = aco1, aco2
|
||||
allow = aco3, aco4
|
||||
|
||||
;-------------------------------------
|
||||
;Groups
|
||||
;-------------------------------------
|
||||
|
||||
[groupname-goes-here]
|
||||
deny = aco5, aco6
|
||||
allow = aco7, aco8
|
||||
@@ -1,32 +0,0 @@
|
||||
<?php
|
||||
/* REQUIRED - APP_NAME is used on all <title>s and mail names/subjects. APP_BASE
|
||||
* should be a FQDN with protocol minus the trailing slash e.g. http://example.tld/party
|
||||
*/
|
||||
define('APP_NAME', '');
|
||||
define('APP_EMAIL', '');
|
||||
define('APP_BASE', '');
|
||||
|
||||
/* You should specify a Google Map API key here. Without it, all mapping features
|
||||
* will be disabled. To obtain a key, visit http://www.google.com/apis/maps/
|
||||
*/
|
||||
define('GMAP_API_KEY', '');
|
||||
|
||||
/* The search API key is used to generate spelling suggestions for locations not
|
||||
* not found during a Geocode operation. You may obtain a key here: http://code.google.com/apis/soapsearch/
|
||||
*/
|
||||
define('GSEARCH_API_KEY', '');
|
||||
|
||||
/* The maximum year shown for party registrations */
|
||||
define('MAX_YEAR', 2007);
|
||||
|
||||
/* The Flickr API is used to show photos of each party on the individual party
|
||||
* pages and home page. See http://flickr.com/services/api/keys/ to obtain a key
|
||||
*/
|
||||
define('FLICKR_API_KEY', '');
|
||||
|
||||
/* The tag prefix is used to limit the results returned to a specific party.
|
||||
* e.g. any photo tagged with FirefoxParty11 will be shown on party 11's page.
|
||||
* Photos tagged with only the prefix are shown on the front page (so choose wisely! ;) ).
|
||||
*/
|
||||
define('FLICKR_TAG_PREFIX', '');
|
||||
?>
|
||||
@@ -1,147 +0,0 @@
|
||||
<?php
|
||||
/* SVN FILE: $Id: core.php,v 1.4 2006-10-08 03:39:21 reed%reedloden.com Exp $ */
|
||||
/**
|
||||
* This is core configuration file.
|
||||
*
|
||||
* Use it to configure core behaviour ofCake.
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
*
|
||||
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
|
||||
* Copyright (c) 2006, Cake Software Foundation, Inc.
|
||||
* 1785 E. Sahara Avenue, Suite 490-204
|
||||
* Las Vegas, Nevada 89104
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @filesource
|
||||
* @copyright Copyright (c) 2006, Cake Software Foundation, Inc.
|
||||
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
|
||||
* @package cake
|
||||
* @subpackage cake.app.config
|
||||
* @since CakePHP v 0.2.9
|
||||
* @version $Revision: 1.4 $
|
||||
* @modifiedby $LastChangedBy: phpnut $
|
||||
* @lastmodified $Date: 2006-10-08 03:39:21 $
|
||||
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
||||
*/
|
||||
/**
|
||||
* If you do not have mod rewrite on your system
|
||||
* or if you prefer to use CakePHP pretty urls.
|
||||
* uncomment the line below.
|
||||
* Note: If you do have mod rewrite but prefer the
|
||||
* CakePHP pretty urls, you also have to remove the
|
||||
* .htaccess files
|
||||
* release/.htaccess
|
||||
* release/app/.htaccess
|
||||
* release/app/webroot/.htaccess
|
||||
*/
|
||||
// define ('BASE_URL', env('SCRIPT_NAME'));
|
||||
/**
|
||||
* Set debug level here:
|
||||
* - 0: production
|
||||
* - 1: development
|
||||
* - 2: full debug with sql
|
||||
* - 3: full debug with sql and dump of the current object
|
||||
*
|
||||
* In production, the "flash messages" redirect after a time interval.
|
||||
* With the other debug levels you get to click the "flash message" to continue.
|
||||
*
|
||||
*/
|
||||
define('DEBUG', 0);
|
||||
/**
|
||||
* Turn of caching checking wide.
|
||||
* You must still use the controller var cacheAction inside you controller class.
|
||||
* You can either set it controller wide, or in each controller method.
|
||||
* use var $cacheAction = true; or in the controller method $this->cacheAction = true;
|
||||
*/
|
||||
define('CACHE_CHECK', false);
|
||||
/**
|
||||
* Error constant. Used for differentiating error logging and debugging.
|
||||
* Currently PHP supports LOG_DEBUG
|
||||
*/
|
||||
define('LOG_ERROR', 2);
|
||||
/**
|
||||
* CakePHP includes 3 types of session saves
|
||||
* database or file. Set this to your preferred method.
|
||||
* If you want to use your own save handler place it in
|
||||
* app/config/name.php DO NOT USE file or database as the name.
|
||||
* and use just the name portion below.
|
||||
*
|
||||
* Setting this to cake will save files to /cakedistro/tmp directory
|
||||
* Setting it to php will use the php default save path
|
||||
* Setting it to database will use the database
|
||||
*
|
||||
*
|
||||
*/
|
||||
define('CAKE_SESSION_SAVE', 'database');
|
||||
/**
|
||||
* If using you own table name for storing sessions
|
||||
* set the table name here.
|
||||
* DO NOT INCLUDE PREFIX IF YOU HAVE SET ONE IN database.php
|
||||
*
|
||||
*/
|
||||
define('CAKE_SESSION_TABLE', 'sessions');
|
||||
/**
|
||||
* Set a random string of used in session.
|
||||
*
|
||||
*/
|
||||
define('CAKE_SESSION_STRING', 'DYhG93b0qyJfIxfs2guVoUubWwvniR2G0FgaC9mi');
|
||||
/**
|
||||
* Set the name of session cookie
|
||||
*
|
||||
*/
|
||||
define('CAKE_SESSION_COOKIE', 'sess');
|
||||
/**
|
||||
* Set level of Cake security.
|
||||
*
|
||||
*/
|
||||
define('CAKE_SECURITY', 'high');
|
||||
/**
|
||||
* Set Cake Session time out.
|
||||
* If CAKE_SECURITY define is set
|
||||
* high: multiplied by 10
|
||||
* medium: is multiplied by 100
|
||||
* low is: multiplied by 300
|
||||
*
|
||||
* Number below is seconds.
|
||||
*/
|
||||
define('CAKE_SESSION_TIMEOUT', '120');
|
||||
/**
|
||||
* Uncomment the define below to use cake built in admin routes.
|
||||
* You can set this value to anything you want.
|
||||
* All methods related to the admin route should be prefixed with the
|
||||
* name you set CAKE_ADMIN to.
|
||||
* For example: admin_index, admin_edit
|
||||
*/
|
||||
// define('CAKE_ADMIN', 'admin');
|
||||
/**
|
||||
* The define below is used to turn cake built webservices
|
||||
* on or off. Default setting is off.
|
||||
*/
|
||||
define('WEBSERVICES', 'off');
|
||||
/**
|
||||
* Compress output CSS (removing comments, whitespace, repeating tags etc.)
|
||||
* This requires a/var/cache directory to be writable by the web server (caching).
|
||||
* To use, prefix the CSS link URL with '/ccss/' instead of '/css/' or use Controller::cssTag().
|
||||
*/
|
||||
define('COMPRESS_CSS', false);
|
||||
/**
|
||||
* If set to true, helpers would output data instead of returning it.
|
||||
*/
|
||||
define('AUTO_OUTPUT', false);
|
||||
/**
|
||||
* If set to false, session would not automatically be started.
|
||||
*/
|
||||
define('AUTO_SESSION', true);
|
||||
/**
|
||||
* Set the max size of file to use md5() .
|
||||
*/
|
||||
define('MAX_MD5SIZE', (5 * 1024) * 1024);
|
||||
/**
|
||||
* To use Access Control Lists with Cake...
|
||||
*/
|
||||
define('ACL_CLASSNAME', 'DB_ACL');
|
||||
define('ACL_FILENAME', 'dbacl' . DS . 'db_acl');
|
||||
?>
|
||||
@@ -1,11 +0,0 @@
|
||||
<?php
|
||||
|
||||
class DATABASE_CONFIG {
|
||||
var $default = array('driver' => 'mysql',
|
||||
'connect' => 'mysql_connect',
|
||||
'host' => 'localhost',
|
||||
'login' => '',
|
||||
'password' => '',
|
||||
'database' => '');
|
||||
}
|
||||
?>
|
||||
@@ -1,72 +0,0 @@
|
||||
<?php
|
||||
/* SVN FILE: $Id: inflections.php,v 1.3 2006-10-08 03:39:21 reed%reedloden.com Exp $ */
|
||||
/**
|
||||
* Custom Inflected Words.
|
||||
*
|
||||
* This file is used to hold words that are not matched in the normail Inflector::pluralize() and
|
||||
* Inflector::singularize()
|
||||
*
|
||||
* PHP versions 4 and %
|
||||
*
|
||||
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
|
||||
* Copyright (c) 2006, Cake Software Foundation, Inc.
|
||||
* 1785 E. Sahara Avenue, Suite 490-204
|
||||
* Las Vegas, Nevada 89104
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @filesource
|
||||
* @copyright Copyright (c) 2006, Cake Software Foundation, Inc.
|
||||
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
|
||||
* @package cake
|
||||
* @subpackage cake.app.config
|
||||
* @since CakePHP v 1.0.0.2312
|
||||
* @version $Revision: 1.3 $
|
||||
* @modifiedby $LastChangedBy: phpnut $
|
||||
* @lastmodified $Date: 2006-10-08 03:39:21 $
|
||||
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
||||
*/
|
||||
/**
|
||||
* This is a key => value array of regex used to match words.
|
||||
* If key matches then the value is returned.
|
||||
*
|
||||
* $pluralRules = array('/(s)tatus$/i' => '\1\2tatuses', '/^(ox)$/i' => '\1\2en', '/([m|l])ouse$/i' => '\1ice');
|
||||
*/
|
||||
$pluralRules = array();
|
||||
/**
|
||||
* This is a key only array of plural words that should not be inflected.
|
||||
* Notice the last comma
|
||||
*
|
||||
* $uninflectedPlural = array('.*[nrlm]ese', '.*deer', '.*fish', '.*measles', '.*ois', '.*pox');
|
||||
*/
|
||||
$uninflectedPlural = array();
|
||||
/**
|
||||
* This is a key => value array of plural irregular words.
|
||||
* If key matches then the value is returned.
|
||||
*
|
||||
* $irregularPlural = array('atlas' => 'atlases', 'beef' => 'beefs', 'brother' => 'brothers')
|
||||
*/
|
||||
$irregularPlural = array();
|
||||
/**
|
||||
* This is a key => value array of regex used to match words.
|
||||
* If key matches then the value is returned.
|
||||
*
|
||||
* $singularRules = array('/(s)tatuses$/i' => '\1\2tatus', '/(matr)ices$/i' =>'\1ix','/(vert|ind)ices$/i')
|
||||
*/
|
||||
$singularRules = array();
|
||||
/**
|
||||
* This is a key only array of singular words that should not be inflected.
|
||||
* You should not have to change this value below if you do change it use same format
|
||||
* as the $uninflectedPlural above.
|
||||
*/
|
||||
$uninflectedSingular = $uninflectedPlural;
|
||||
/**
|
||||
* This is a key => value array of singular irregular words.
|
||||
* Most of the time this will be a reverse of the above $irregularPlural array
|
||||
* You should not have to change this value below if you do change it use same format
|
||||
*
|
||||
* $irregularSingular = array('atlases' => 'atlas', 'beefs' => 'beef', 'brothers' => 'brother')
|
||||
*/
|
||||
$irregularSingular = array_flip($irregularPlural);
|
||||
?>
|
||||
@@ -1,43 +0,0 @@
|
||||
<?php
|
||||
/* SVN FILE: $Id: routes.php,v 1.5 2006-10-10 20:18:59 reed%reedloden.com Exp $ */
|
||||
/**
|
||||
* Short description for file.
|
||||
*
|
||||
* In this file, you set up routes to your controllers and their actions.
|
||||
* Routes are very important mechanism that allows you to freely connect
|
||||
* different urls to chosen controllers and their actions (functions).
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
*
|
||||
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
|
||||
* Copyright (c) 2006, Cake Software Foundation, Inc.
|
||||
* 1785 E. Sahara Avenue, Suite 490-204
|
||||
* Las Vegas, Nevada 89104
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @filesource
|
||||
* @copyright Copyright (c) 2006, Cake Software Foundation, Inc.
|
||||
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
|
||||
* @package cake
|
||||
* @subpackage cake.app.config
|
||||
* @since CakePHP v 0.2.9
|
||||
* @version $Revision: 1.5 $
|
||||
* @modifiedby $LastChangedBy: phpnut $
|
||||
* @lastmodified $Date: 2006-10-10 20:18:59 $
|
||||
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
||||
*/
|
||||
/**
|
||||
* Here, we are connecting '/' (base path) to controller called 'Pages',
|
||||
* its action called 'display', and we pass a param to select the view file
|
||||
* to use (in this case, /app/views/pages/home.thtml)...
|
||||
*/
|
||||
$Route->connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));
|
||||
/**
|
||||
* ...and connect the rest of 'Pages' controller's urls.
|
||||
*/
|
||||
$Route->connect('/pages/edit', array('controller' => 'pages', 'action' => 'edit'));
|
||||
$Route->connect('/pages/*', array('controller' => 'pages', 'action' => 'display'));
|
||||
$Route->connect('/privacy-policy', array('controller' => 'pages', 'action' => 'privacy'));
|
||||
?>
|
||||
@@ -1,80 +0,0 @@
|
||||
CREATE TABLE `comments` (
|
||||
`id` int(10) NOT NULL auto_increment,
|
||||
`assoc` int(10) NOT NULL default '0',
|
||||
`owner` int(10) NOT NULL default '0',
|
||||
`time` int(15) NOT NULL default '0',
|
||||
`text` text collate utf8_unicode_ci NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||
|
||||
CREATE TABLE `guests` (
|
||||
`id` int(10) NOT NULL auto_increment,
|
||||
`pid` int(10) NOT NULL default '0',
|
||||
`uid` int(10) NOT NULL default '0',
|
||||
`invited` tinyint(1) NOT NULL default '1',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `pid` (`pid`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||
|
||||
CREATE TABLE `pages` (
|
||||
`id` int(10) NOT NULL auto_increment,
|
||||
`text` text collate utf8_unicode_ci NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||
|
||||
INSERT INTO `pages` (`id`, `text`) VALUES (1, '<h2>Join the Fun!</h2>\n<p>All over the world, we're celebrating the launch of Firefox 2. Join the fun by hosting or attending a party. We're targeting the weekend of October 27th for the shared celebration, but if you're hosting, you make the call.</p>\n\n<p>To join the fun, <a href="/users/register">register</a> for a Firefox Party account, and sign up to host or attend.</p>\n\n<p style="border: 1px solid #555; background: #faffd4; padding: 5px; font-weight: bold">Be one of the first 50 party hosts registered and get three extra launch exclusive t-shirts with your purchase of the <a href="">Firefox 2 Party Pack</a>. We're selling the party packs and shirts at cost, so it's a great deal, and for parties with unusually large attendance, we'll be sending out additional swag for door prizes and other give-aways. Stay tuned for updates!</p>');
|
||||
INSERT INTO `pages` (`id`, `text`) VALUES (2, '1162007940');
|
||||
|
||||
CREATE TABLE `parties` (
|
||||
`id` int(10) NOT NULL auto_increment,
|
||||
`owner` int(10) NOT NULL default '0',
|
||||
`name` tinytext collate utf8_unicode_ci NOT NULL,
|
||||
`vname` tinytext collate utf8_unicode_ci NOT NULL,
|
||||
`address` tinytext collate utf8_unicode_ci NOT NULL,
|
||||
`tz` int(2) NOT NULL default '0',
|
||||
`website` text collate utf8_unicode_ci NOT NULL,
|
||||
`notes` text collate utf8_unicode_ci NOT NULL,
|
||||
`date` int(10) NOT NULL default '0',
|
||||
`duration` tinyint(2) NOT NULL default '2',
|
||||
`confirmed` tinyint(1) NOT NULL default '1',
|
||||
`canceled` tinyint(1) NOT NULL default '0',
|
||||
`guestcomments` tinyint(1) NOT NULL default '0',
|
||||
`inviteonly` tinyint(1) NOT NULL default '0',
|
||||
`invitecode` tinytext collate utf8_unicode_ci NOT NULL,
|
||||
`lat` float NOT NULL default '0',
|
||||
`long` float NOT NULL default '0',
|
||||
`zoom` tinyint(2) NOT NULL default '1',
|
||||
`useflickr` tinyint(1) NOT NULL default '0',
|
||||
`flickrperms` tinyint(1) NOT NULL default '0',
|
||||
`flickrid` tinytext collate utf8_unicode_ci NOT NULL,
|
||||
`flickrusr` tinytext collate utf8_unicode_ci NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||
|
||||
CREATE TABLE `sessions` (
|
||||
`id` varchar(255) character set latin1 NOT NULL default '',
|
||||
`data` text character set latin1,
|
||||
`expires` int(11) default NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||
|
||||
CREATE TABLE `users` (
|
||||
`id` int(10) NOT NULL auto_increment,
|
||||
`role` tinyint(1) NOT NULL default '0',
|
||||
`email` varchar(255) collate utf8_unicode_ci NOT NULL,
|
||||
`active` varchar(10) collate utf8_unicode_ci NOT NULL default '0',
|
||||
`password` varchar(75) collate utf8_unicode_ci NOT NULL default '',
|
||||
`salt` varchar(9) collate utf8_unicode_ci NOT NULL default '',
|
||||
`name` tinytext collate utf8_unicode_ci NOT NULL,
|
||||
`location` tinytext collate utf8_unicode_ci NOT NULL,
|
||||
`tz` tinyint(2) NOT NULL default '0',
|
||||
`website` text collate utf8_unicode_ci NOT NULL,
|
||||
`lat` float NOT NULL default '0',
|
||||
`long` float NOT NULL default '0',
|
||||
`zoom` tinyint(2) NOT NULL default '1',
|
||||
`showemail` tinyint(1) NOT NULL default '0',
|
||||
`showloc` tinyint(1) NOT NULL default '1',
|
||||
`showmap` tinyint(1) NOT NULL default '1',
|
||||
UNIQUE KEY `email` (`email`),
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
||||
@@ -1,163 +0,0 @@
|
||||
<?php
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Party Tool
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Ryan Flint <rflint@dslr.net>
|
||||
* Portions created by the Initial Developer are Copyright (C) 2006
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
uses('sanitize');
|
||||
class AdminController extends AppController {
|
||||
var $name = 'Admin';
|
||||
var $uses = array('Party', 'User', 'Comment');
|
||||
var $components = array('Unicode');
|
||||
|
||||
function beforeFilter() {
|
||||
if (empty($_SESSION['User']) || $_SESSION['User']['role'] != 1) {
|
||||
$this->redirect('/');
|
||||
die();
|
||||
}
|
||||
}
|
||||
|
||||
function index() {
|
||||
$this->set('parties', $this->Party->findAll(null, null, "id ASC"));
|
||||
}
|
||||
|
||||
function users() {
|
||||
$this->set('users', $this->User->findAll(null, null, "id ASC"));
|
||||
}
|
||||
|
||||
function comments() {
|
||||
$this->set('comments', $this->Comment->findAll(null, null, "id ASC"));
|
||||
}
|
||||
|
||||
function edit($type, $id) {
|
||||
if (empty($this->data)) {
|
||||
switch($type) {
|
||||
case 'user':
|
||||
$this->User->id = $id;
|
||||
$user = $this->User->read();
|
||||
$this->set('user', $user);
|
||||
$this->data = $user;
|
||||
break;
|
||||
|
||||
case 'party':
|
||||
$this->Party->id = $id;
|
||||
$party = $this->Party->read();
|
||||
$this->set('party', $party);
|
||||
$this->data = $party;
|
||||
$this->data['Party']['name'] = preg_replace("/&#(\d{2,5});/e",
|
||||
'$this->Unicode->unicode2utf(${1})',
|
||||
html_entity_decode($this->data['Party']['name']));
|
||||
$this->data['Party']['vname'] = preg_replace("/&#(\d{2,5});/e",
|
||||
'$this->Unicode->unicode2utf(${1})',
|
||||
html_entity_decode($this->data['Party']['vname']));
|
||||
$this->data['Party']['website'] = preg_replace("/&#(\d{2,5});/e",
|
||||
'$this->Unicode->unicode2utf(${1})',
|
||||
html_entity_decode($this->data['Party']['website']));
|
||||
$this->data['Party']['address'] = preg_replace("/&#(\d{2,5});/e",
|
||||
'$this->Unicode->unicode2utf(${1})',
|
||||
html_entity_decode($this->data['Party']['address']));
|
||||
$this->data['Party']['notes'] = preg_replace("/&#(\d{2,5});/e",
|
||||
'$this->Unicode->unicode2utf(${1})',
|
||||
html_entity_decode($this->data['Party']['notes']));
|
||||
$this->data['Party']['flickrusr'] = preg_replace("/&#(\d{2,5});/e",
|
||||
'$this->Unicode->unicode2utf(${1})',
|
||||
html_entity_decode($this->data['Party']['flickrusr']));
|
||||
break;
|
||||
|
||||
case 'comment':
|
||||
$this->Comment->id = $id;
|
||||
$comment = $this->Comment->read();
|
||||
$this->set('comment', $comment);
|
||||
|
||||
$uid = $this->User->findById($comment['Comment']['owner']);
|
||||
$this->set('owner', $uid['User']['name']);
|
||||
|
||||
$this->data = $comment;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
switch($type) {
|
||||
case 'user':
|
||||
$this->User->id = $id;
|
||||
$this->User->save($this->data);
|
||||
break;
|
||||
|
||||
case 'party':
|
||||
$this->Party->id = $id;
|
||||
$clean = new Sanitize();
|
||||
$clean->cleanArray($this->data);
|
||||
$this->Party->save($this->data);
|
||||
break;
|
||||
|
||||
case 'comment':
|
||||
$this->Comment->id = $id;
|
||||
$this->Comment->save($this->data);
|
||||
break;
|
||||
}
|
||||
|
||||
if ($type != 'party')
|
||||
$this->redirect('/admin/'.$type.'s');
|
||||
|
||||
else
|
||||
$this->redirect('/admin/');
|
||||
}
|
||||
}
|
||||
|
||||
function delete($type, $id) {
|
||||
switch($type) {
|
||||
case 'user':
|
||||
$this->User->del($id);
|
||||
$this->User->query("DELETE FROM guests WHERE uid = $id");
|
||||
break;
|
||||
|
||||
case 'party':
|
||||
$this->Party->del($id);
|
||||
$this->Party->query("DELETE FROM guests WHERE pid = $id");
|
||||
$this->Party->query("DELETE FROM comments WHERE assoc = $id");
|
||||
break;
|
||||
|
||||
case 'comment':
|
||||
$this->Comment->del($id);
|
||||
break;
|
||||
}
|
||||
|
||||
if ($type != 'party')
|
||||
$this->redirect('/admin/'.$type.'s');
|
||||
|
||||
else
|
||||
$this->redirect('/admin/');
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -1,71 +0,0 @@
|
||||
<?php
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Party Tool
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Ryan Flint <rflint@dslr.net>
|
||||
* Portions created by the Initial Developer are Copyright (C) 2006
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
uses('sanitize');
|
||||
|
||||
class CommentsController extends AppController {
|
||||
var $name = 'Comments';
|
||||
var $components = array('Security');
|
||||
|
||||
function beforeFilter() {
|
||||
$this->Security->requirePost('add');
|
||||
}
|
||||
|
||||
function add($pid, $uid) {
|
||||
if (!$this->Session->check('User') || $uid != $_SESSION['User']['id'])
|
||||
$this->redirect('/');
|
||||
|
||||
if (!empty($this->data) && $this->Comment->canComment($pid, $uid)) {
|
||||
// Explictly destroy the last model to avoid an edit instead of an insert
|
||||
$this->Comment->create();
|
||||
|
||||
$clean = new Sanitize();
|
||||
$text = $clean->html($this->data['Comment']['text']);
|
||||
$this->data['Comment']['text'] = nl2br($text);
|
||||
$this->data['Comment']['owner'] = $uid;
|
||||
$this->data['Comment']['assoc'] = $pid;
|
||||
$this->data['Comment']['time'] = mktime();
|
||||
|
||||
if ($this->Comment->save($this->data)) {
|
||||
$this->redirect('/parties/view/'.$pid.'#c'.$this->Comment->getLastInsertID());
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
$this->redirect('/parties/view/'.$pid);
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -1,54 +0,0 @@
|
||||
<?php
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Party Tool
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Ryan Flint <rflint@dslr.net>
|
||||
* Portions created by the Initial Developer are Copyright (C) 2006
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
class HashComponent extends Object {
|
||||
|
||||
function password($pass, $data) {
|
||||
$string = $pass.uniqid(rand(), true).$data;
|
||||
$salt = substr(md5($string), 0, 9);
|
||||
$p = sha1($pass.$salt);
|
||||
$rv = array('pass' => $p, 'salt' => $salt);
|
||||
return $rv;
|
||||
}
|
||||
|
||||
function keygen($chars) {
|
||||
$key = null;
|
||||
$pool = "abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
for ($i = 0; $i < $chars; $i++)
|
||||
$key .= $pool{rand(0,61)};
|
||||
return $key;
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
<?php
|
||||
class MailComponent extends Object {
|
||||
var $from;
|
||||
var $to;
|
||||
var $reply;
|
||||
var $subject;
|
||||
var $message;
|
||||
var $envelope;
|
||||
var $head = "<strong>Firefox Party!</strong><br/>";
|
||||
var $foot;
|
||||
|
||||
|
||||
function mail($params) {
|
||||
if (array_key_exists('from', $params))
|
||||
$this->from = $params['from'];
|
||||
|
||||
if (array_key_exists('to', $params))
|
||||
$this->to = $params['to'];
|
||||
|
||||
if (array_key_exists('reply', $params))
|
||||
$this->reply = $params['reply'];
|
||||
|
||||
if (array_key_exists('subject', $params))
|
||||
$this->subject = $params['subject'];
|
||||
|
||||
if (array_key_exists('message', $params))
|
||||
$this->message = $params['message'];
|
||||
|
||||
if (array_key_exists('envelope', $params))
|
||||
$this->envelope = $params['envelope'];
|
||||
|
||||
if (array_key_exists('type', $params)) {
|
||||
switch($params['type']) {
|
||||
case 'act':
|
||||
$this->message = $this->head."<br/>\nThank you for registering! To activate your account, <a href=\"".$params['link']."\">click here</a> or paste the link below into your browser:<br/> ".$params['link'].$this->foot;
|
||||
break;
|
||||
|
||||
case 'prec':
|
||||
$this->message = $this->head."<br/>\nTo reset your password, <a href=\"".$params['link']."\">click here</a> or paste the link below into your browser:<br/> ".$params['link'].$this->foot;
|
||||
break;
|
||||
|
||||
case 'invite':
|
||||
$this->message = $this->head."<br/>\nYou've been invited by a friend to join them in celebrating the release of Firefox 2. Simply <a href=\"".$params['link']."\">click here</a> to confirm or cancel this invitation. If you don't already have an account, you'll need to create one.\n
|
||||
If you're unable to use the link above, simply paste the following URL into your browser: ".$params['link'].$this->foot;
|
||||
break;
|
||||
|
||||
case 'cancel':
|
||||
$this->message = $this->head."<br/>\nThe party you were attending has been canceled. For more information, please <a href=\"".$params['link']."\">click here</a>, or see the link below.\n ".$params['link'].$this->foot;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function make_headers($type='html') {
|
||||
$headers = '';
|
||||
|
||||
switch($type) {
|
||||
case 'html':
|
||||
$headers .= 'MIME-Version: 1.0' . "\r\n";
|
||||
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
|
||||
break;
|
||||
}
|
||||
|
||||
if (!empty($this->from)) {
|
||||
$headers .= "From: {$this->from}\r\n";
|
||||
|
||||
if (!empty($this->reply))
|
||||
$headers .= "Reply-To: {$this->reply}\r\n";
|
||||
}
|
||||
return $headers;
|
||||
}
|
||||
|
||||
function make_additional_parameters() {
|
||||
if (!empty($this->envelope)) {
|
||||
return '-f'.$this->envelope;
|
||||
}
|
||||
}
|
||||
|
||||
function send() {
|
||||
mail($this->to, $this->subject, $this->message, $this->make_headers(), $this->make_additional_parameters());
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -1,75 +0,0 @@
|
||||
<?php
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Party Tool
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Ryan Flint <rflint@dslr.net>
|
||||
* Portions created by the Initial Developer are Copyright (C) 2006
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
class UnicodeComponent extends Object {
|
||||
/**
|
||||
* Unicode utilities. Converts and encodes characters up to 0xFFFF (65535)
|
||||
*/
|
||||
function unicode2utf($char) {
|
||||
if ($char < 128) {
|
||||
$rv = chr($char);
|
||||
}
|
||||
|
||||
else if ($char < 2048) {
|
||||
$rv = chr(192 + (($char - ($char % 64)) / 64));
|
||||
$rv .= chr(128 + ($char % 64));
|
||||
}
|
||||
|
||||
else {
|
||||
$rv = chr(224 + (($char - ($char % 4096)) / 4096));
|
||||
$rv .= chr(128 + ((($char % 4096) - ($char % 64)) / 64));
|
||||
$rv .= chr(128 + ($char % 64));
|
||||
}
|
||||
|
||||
return $rv;
|
||||
}
|
||||
|
||||
function utf2unicode($char) {
|
||||
if (ord($char{0}) < 128)
|
||||
$rv = ord($char);
|
||||
|
||||
else if (ord($char{0}) < 224)
|
||||
$rv = ((ord($char{0}) - 192) * 64) + (ord($char{1}) - 128);
|
||||
|
||||
else if (ord($char{0}) < 240)
|
||||
$rv = ((ord($char{0}) - 224) * 4096) + ((ord($char{1}) - 128) * 64 + (ord($char{2}) - 128));
|
||||
|
||||
else
|
||||
$rv = ((ord($char{0}) - 240) * 262144) + ((ord($char{1}) - 128) * 4096) + ((ord($char{2}) - 128) * 64) + (ord($char{3}) - 128);
|
||||
|
||||
return $rv;
|
||||
}
|
||||
}
|
||||
@@ -1,143 +0,0 @@
|
||||
<?php
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Party Tool
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Ryan Flint <rflint@dslr.net>
|
||||
* Portions created by the Initial Developer are Copyright (C) 2006
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
vendor('webServices');
|
||||
class FeedsController extends AppController {
|
||||
var $name = 'Feeds';
|
||||
var $components = array('Unicode');
|
||||
|
||||
function index() {
|
||||
header('Content-type: application/rss+xml');
|
||||
$this->layout = 'ajax';
|
||||
$this->set('count', $this->Feed->findCount());
|
||||
}
|
||||
|
||||
function latest() {
|
||||
header('Content-type: application/rss+xml');
|
||||
$this->layout = 'ajax';
|
||||
$this->set('latest', $this->Feed->findAll('', '', 'id DESC', 10, 1));
|
||||
}
|
||||
|
||||
function users() {
|
||||
header('Content-type: application/rss+xml');
|
||||
$this->layout = 'ajax';
|
||||
$this->set('count', $this->Feed->getUserCount());
|
||||
}
|
||||
|
||||
function comments($id = null) {
|
||||
$this->layout = 'ajax';
|
||||
header('Content-type: application/rss+xml');
|
||||
if (!is_numeric($id))
|
||||
return;
|
||||
|
||||
$this->set('comments', $this->Feed->getComments($id));
|
||||
$this->set('pid', $id);
|
||||
}
|
||||
|
||||
function photos($id = null) {
|
||||
$this->layout = 'ajax';
|
||||
header('Content-type: application/atom+xml');
|
||||
if (!is_numeric($id))
|
||||
return;
|
||||
|
||||
$party = $this->Feed->findById($id);
|
||||
$this->set('party', $party);
|
||||
|
||||
if (FLICKR_API_KEY != null && !$party['Feeds']['canceled']) {
|
||||
if ($party['Feeds']['useflickr'] == 1) {
|
||||
$data = array('type' => 'flickr', 'userid' => $party['Feeds']['flickrid'], 'randomize' => false);
|
||||
$flickr = new webServices($data);
|
||||
$photoset = $flickr->fetchPhotos(FLICKR_TAG_PREFIX.$id, 30, !$party['Feeds']['flickrperms']);
|
||||
$this->set('flickr', $photoset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function upcoming($limit = null) {
|
||||
$this->layout = 'ajax';
|
||||
header('Content-type: application/rss+xml');
|
||||
|
||||
($limit == null) ? $limit = 25 : $limit = intval($limit);
|
||||
|
||||
$this->set('latest', $this->Feed->findAll('WHERE date > '. time(), '', 'date ASC', $limit, 1));
|
||||
}
|
||||
|
||||
function ical() {
|
||||
$this->layout = 'ajax';
|
||||
header('Content-type: text/calendar');
|
||||
header("Content-Disposition: inline; filename=partylist.ics");
|
||||
$back = time() - 172800;
|
||||
$events = $this->Feed->findAll('WHERE date > '. $back, '', 'date ASC', null, 1);
|
||||
|
||||
$cal = array();
|
||||
|
||||
foreach($events as $event) {
|
||||
$event['Feeds']['name'] =
|
||||
preg_replace(array("/&#(\d{2,5});/e", "/(\n|\r|\f)/", "/\,/"),
|
||||
array('$this->Unicode->unicode2utf(${1})', ' ', '\,'),
|
||||
html_entity_decode($event['Feeds']['name']));
|
||||
$event['Feeds']['address'] =
|
||||
preg_replace(array("/&#(\d{2,5});/e", "/(\n|\r|\f)/", "/\,/"),
|
||||
array('$this->Unicode->unicode2utf(${1})', ' ', '\,'),
|
||||
html_entity_decode($event['Feeds']['address']));
|
||||
$event['Feeds']['notes'] =
|
||||
preg_replace(array("/&#(\d{2,5});/e", "/(\n|\r|\f)/", "/\,/"),
|
||||
array('$this->Unicode->unicode2utf(${1})', ' ', '\,'),
|
||||
html_entity_decode($event['Feeds']['notes']));
|
||||
array_push($cal, $event);
|
||||
}
|
||||
$this->set('events', $cal);
|
||||
}
|
||||
|
||||
function topguests($limit = null) {
|
||||
$this->layout = 'ajax';
|
||||
header('Content-type: application/rss+xml');
|
||||
|
||||
($limit == null) ? $limit = 25 : $limit = intval($limit);
|
||||
|
||||
$rv = $this->Feed->query("SELECT parties.name AS name,
|
||||
guests.pid AS id,
|
||||
COUNT(guests.pid) AS count
|
||||
FROM guests
|
||||
LEFT JOIN parties
|
||||
ON guests.pid = parties.id
|
||||
GROUP BY guests.pid
|
||||
ORDER BY count DESC
|
||||
LIMIT $limit");
|
||||
$this->set('items', $rv);
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -1,92 +0,0 @@
|
||||
<?php
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Party Tool
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Ryan Flint <rflint@dslr.net>
|
||||
* Portions created by the Initial Developer are Copyright (C) 2006
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
uses('sanitize');
|
||||
class PagesController extends AppController {
|
||||
var $name = 'Pages';
|
||||
var $components = array('Unicode');
|
||||
|
||||
function display() {
|
||||
$this->pageTitle = 'Home';
|
||||
$this->set('current', 'home');
|
||||
$this->set('pcount', $this->Page->findCount());
|
||||
$this->set('ucount', $this->Page->getUsers());
|
||||
$text = $this->Page->query('SELECT text FROM pages WHERE id = 1');
|
||||
$time = $this->Page->query('SELECT text FROM pages WHERE id = 2');
|
||||
$this->set('time', $time[0]['pages']['text']);
|
||||
$this->set('front_text', preg_replace("/&#(\d{2,5});/e",
|
||||
'$this->Unicode->unicode2utf(${1})',
|
||||
html_entity_decode($text[0]['pages']['text'])));
|
||||
}
|
||||
|
||||
function privacy() {
|
||||
$this->pageTitle = 'Privacy Policy';
|
||||
}
|
||||
|
||||
function edit() {
|
||||
if (isset($_SESSION['User']['id']) && $_SESSION['User']['role'] == 1) {
|
||||
if (empty($this->data)) {
|
||||
$text = $this->Page->query('SELECT text FROM pages WHERE id = 1');
|
||||
$time = $this->Page->query('SELECT text FROM pages WHERE id = 2');
|
||||
$this->data['Pages']['text'] = preg_replace("/&#(\d{2,5});/e",
|
||||
'$this->Unicode->unicode2utf(${1})',
|
||||
html_entity_decode($text[0]['pages']['text']));
|
||||
$this->set('selected', date('Y-m-d H:i:s', $time[0]['pages']['text']));
|
||||
}
|
||||
|
||||
else {
|
||||
// Paranoid? Nah...
|
||||
if ($_SESSION['User']['role'] == 1) {
|
||||
$clean = new Sanitize();
|
||||
$clean->cleanArray($this->data);
|
||||
$date = mktime($this->data['Pages']['date_hour'],
|
||||
$this->data['Pages']['date_min'],
|
||||
0,
|
||||
$this->data['Pages']['date_month'],
|
||||
$this->data['Pages']['date_day'],
|
||||
$this->data['Pages']['date_year']);
|
||||
|
||||
$this->Page->execute('UPDATE pages SET text = "'.$this->data['Pages']['text'].'" WHERE pages.id = 1');
|
||||
$this->Page->execute('UPDATE pages SET text = "'.$date.'" WHERE pages.id = 2');
|
||||
$this->redirect('/');
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
die();
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -1,472 +0,0 @@
|
||||
<?php
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Party Tool
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Ryan Flint <rflint@dslr.net>
|
||||
* Portions created by the Initial Developer are Copyright (C) 2006
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
uses('sanitize');
|
||||
vendor('webServices');
|
||||
class PartiesController extends AppController {
|
||||
var $name = 'Parties';
|
||||
var $uses = array('Party', 'Comment');
|
||||
var $helpers = array('Html', 'Form');
|
||||
var $components = array('Hash', 'Mail', 'Unicode');
|
||||
|
||||
function index() {
|
||||
$this->pageTitle = 'Party Map';
|
||||
$this->set('current', 'map');
|
||||
|
||||
if (!empty($this->data)) {
|
||||
$gcoder = new webServices(array('type' => 'geocode'));
|
||||
$loc = $gcoder->geocode($this->data['Party']['mloc']);
|
||||
|
||||
if ($loc)
|
||||
$this->set('map', 'initMashUp('.$loc['lat'].', '.$loc['lng'].');');
|
||||
|
||||
else
|
||||
$this->set('map', 'initMashUp();');
|
||||
}
|
||||
|
||||
else
|
||||
$this->set('map', 'initMashUp();');
|
||||
}
|
||||
|
||||
function add() {
|
||||
if (!$this->Session->check('User'))
|
||||
$this->redirect('/users/login');
|
||||
|
||||
$this->pageTitle = 'Create Party';
|
||||
$this->set('current', 'create');
|
||||
$this->set('map', 'mapInit()');
|
||||
|
||||
if(empty($this->data)) {
|
||||
$this->set('utz', $_SESSION['User']['tz']);
|
||||
$this->render();
|
||||
}
|
||||
|
||||
else {
|
||||
$temp = array('lat' => $this->data['Party']['lat'],
|
||||
'long' => $this->data['Party']['long'],
|
||||
'tz' => $this->data['Party']['tz']);
|
||||
|
||||
$clean = new Sanitize();
|
||||
$clean->cleanArray($this->data);
|
||||
|
||||
$this->data['Party']['lat'] = floatval($temp['lat']);
|
||||
$this->data['Party']['long'] = floatval($temp['long']);
|
||||
$this->data['Party']['tz'] = intval($temp['tz']);
|
||||
$this->set('utz', $this->data['Party']['tz']);
|
||||
|
||||
// Convert the selected time to GMT
|
||||
$secoffset = ($this->data['Party']['tz'] * 60 * 60);
|
||||
$offsetdate = gmmktime($this->data['Party']['hour_hour'],
|
||||
$this->data['Party']['minute_min'],
|
||||
0,
|
||||
$this->data['Party']['month_hour'],
|
||||
$this->data['Party']['day_day'],
|
||||
$this->data['Party']['year_year']);
|
||||
$this->data['Party']['date'] = ($offsetdate + $secoffset);
|
||||
$this->data['Party']['duration'] = intval($this->data['Party']['duration']);
|
||||
|
||||
$this->data['Party']['invitecode'] = $this->Hash->keygen(10);
|
||||
$this->data['Party']['owner'] = $_SESSION['User']['id'];
|
||||
|
||||
if (!preg_match("/^(http|https)\:\/\//i", $this->data['Party']['website']) &&
|
||||
!empty($this->data['Party']['website']))
|
||||
$this->Party->invalidate('website');
|
||||
|
||||
if ($this->Party->validates($this->data)) {
|
||||
if($this->Party->save($this->data)) {
|
||||
$this->Session->setFlash('Your party has been created!', 'infoFlash');
|
||||
$this->redirect('/parties/view/'.$this->Party->getLastInsertId());
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
$this->Session->setFlash('Please correct the errors below.', 'errorFlash');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function edit($id) {
|
||||
$this->Party->id = $id;
|
||||
$party = $this->Party->read();
|
||||
$this->set('party', $party);
|
||||
$this->pageTitle = 'Edit Party';
|
||||
$this->set('current', 'create');
|
||||
|
||||
if (empty($_SESSION['User']['id']))
|
||||
$this->redirect('/users/login/');
|
||||
|
||||
if ($party['Party']['owner'] != $_SESSION['User']['id'])
|
||||
$this->redirect('/parties/view/'.$id);
|
||||
|
||||
else {
|
||||
if (empty($this->data)) {
|
||||
$this->data = $party;
|
||||
|
||||
$date = array('hour' => intval(date('h', $party['Party']['date'])),
|
||||
'min' => intval(date('i', $party['Party']['date'])),
|
||||
'mon' => intval(date('m', $party['Party']['date'])),
|
||||
'day' => intval(date('d', $party['Party']['date'])),
|
||||
'year' => intval(date('Y', $party['Party']['date'])),
|
||||
'tz' => $party['Party']['tz']);
|
||||
|
||||
$this->set('date', $date);
|
||||
$this->data['Party']['name'] = preg_replace("/&#(\d{2,5});/e",
|
||||
'$this->Unicode->unicode2utf(${1})',
|
||||
html_entity_decode($this->data['Party']['name']));
|
||||
$this->data['Party']['vname'] = preg_replace("/&#(\d{2,5});/e",
|
||||
'$this->Unicode->unicode2utf(${1})',
|
||||
html_entity_decode($this->data['Party']['vname']));
|
||||
$this->data['Party']['website'] = preg_replace("/&#(\d{2,5});/e",
|
||||
'$this->Unicode->unicode2utf(${1})',
|
||||
html_entity_decode($this->data['Party']['website']));
|
||||
$this->data['Party']['address'] = preg_replace("/&#(\d{2,5});/e",
|
||||
'$this->Unicode->unicode2utf(${1})',
|
||||
html_entity_decode($this->data['Party']['address']));
|
||||
$this->data['Party']['notes'] = preg_replace("/&#(\d{2,5});/e",
|
||||
'$this->Unicode->unicode2utf(${1})',
|
||||
html_entity_decode($this->data['Party']['notes']));
|
||||
$this->data['Party']['flickrusr'] = preg_replace("/&#(\d{2,5});/e",
|
||||
'$this->Unicode->unicode2utf(${1})',
|
||||
html_entity_decode($this->data['Party']['flickrusr']));
|
||||
|
||||
if (GMAP_API_KEY != null) {
|
||||
if ($this->data['Party']['lat'])
|
||||
$this->set('map', 'mapInit('.$this->data['Party']['lat'].','.$this->data['Party']['long'].','.$this->data['Party']['zoom'].')');
|
||||
else
|
||||
$this->set('map', 'mapInit()');
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
$clean = new Sanitize();
|
||||
$temp = array('lat' => $clean->sql($this->data['Party']['lat']),
|
||||
'long' => $clean->sql($this->data['Party']['long']),
|
||||
'tz' => $clean->sql($this->data['Party']['tz']));
|
||||
|
||||
$clean->cleanArray($this->data);
|
||||
|
||||
$this->data['Party']['lat'] = floatval($temp['lat']);
|
||||
$this->data['Party']['long'] = floatval($temp['long']);
|
||||
$this->data['Party']['tz'] = intval($temp['tz']);
|
||||
|
||||
$secoffset = ($this->data['Party']['tz'] * 60 * 60);
|
||||
|
||||
$offsetdate = gmmktime($this->data['Party']['hour_hour'],
|
||||
$this->data['Party']['minute_min'],
|
||||
0,
|
||||
$this->data['Party']['month_hour'],
|
||||
$this->data['Party']['day_day'],
|
||||
$this->data['Party']['year_year']);
|
||||
|
||||
$this->data['Party']['date'] = ($offsetdate - $secoffset);
|
||||
$this->data['Party']['owner'] = $party['Party']['owner'];
|
||||
$this->data['Party']['duration'] = intval($this->data['Party']['duration']);
|
||||
|
||||
$date = array('hour' => intval(date('h', $party['Party']['date'])),
|
||||
'min' => intval(date('i', $party['Party']['date'])),
|
||||
'mon' => intval(date('m', $party['Party']['date'])),
|
||||
'day' => intval(date('d', $party['Party']['date'])),
|
||||
'year' => intval(date('Y', $party['Party']['date'])),
|
||||
'tz' => $party['Party']['tz']);
|
||||
$this->set('date', $date);
|
||||
|
||||
if (!preg_match("/^(http|https)\:\/\//i", $this->data['Party']['website']) &&
|
||||
!empty($this->data['Party']['website']))
|
||||
$this->Party->invalidate('website');
|
||||
|
||||
if ($this->data['Party']['flickrusr'] != $party['Party']['flickrusr']) {
|
||||
$params = array('type' => 'flickr', 'username' => $this->data['Party']['flickrusr']);
|
||||
$flick = new webServices($params);
|
||||
$this->data['Party']['flickrid'] = $flick->getFlickrId();
|
||||
}
|
||||
|
||||
if ($this->Party->validates($this->data)) {
|
||||
if ($this->Party->save($this->data)) {
|
||||
$this->Session->setFlash('Party edited successfully.', 'infoFlash');
|
||||
$this->redirect('parties/view/'.$id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function view($id = null, $page = null) {
|
||||
if ($id == 'all') {
|
||||
$this->pageTitle = 'All Parties';
|
||||
$this->set('current', 'parties');
|
||||
|
||||
//Paginate!
|
||||
$count = $this->Party->findCount();
|
||||
$pages = ceil($count/100);
|
||||
if ($page == null)
|
||||
$page = 1;
|
||||
if ($page > 1)
|
||||
$this->set('prev', $page - 1);
|
||||
if ($page < $pages)
|
||||
$this->set('next', $page + 1);
|
||||
|
||||
$deck = $this->Party->findAll(null, null, "id ASC", 100, $page);
|
||||
shuffle($deck);
|
||||
$this->set('parties', $deck);
|
||||
}
|
||||
|
||||
else if (is_numeric($id)) {
|
||||
$party = $this->Party->findById($id);
|
||||
if (empty($party['Party']['id']))
|
||||
$this->redirect('/parties/view/all');
|
||||
|
||||
$this->set('current', 'parties');
|
||||
$this->set('host', $this->Party->getHost($party['Party']['owner']));
|
||||
$this->set('party', $party);
|
||||
$this->set('isguest', $this->Party->isGuest($id, @$_SESSION['User']['id']));
|
||||
$this->pageTitle = $party['Party']['name'];
|
||||
$this->set('map', 'mapInit('.$party['Party']['lat'].','.$party['Party']['long'].
|
||||
','.$party['Party']['zoom'].',\'stationary\')');
|
||||
$this->set('guests', $this->Party->getGuests($party['Party']['id']));
|
||||
$this->set('comments', $this->Party->getComments($id));
|
||||
|
||||
if (FLICKR_API_KEY != null) {
|
||||
if ($party['Party']['useflickr'] == 1) {
|
||||
$data = array('type' => 'flickr', 'userid' => $party['Party']['flickrid'], 'randomize' => true);
|
||||
$flickr = new webServices($data);
|
||||
$photoset = $flickr->fetchPhotos(FLICKR_TAG_PREFIX.$party['Party']['id'], 15, (($party['Party']['flickrperms']) ? false : true));
|
||||
$this->set('flickr', array_slice($photoset, 0, 9));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
$this->redirect('/parties/view/all');
|
||||
}
|
||||
|
||||
function invite($id = null) {
|
||||
$this->pageTitle = "Invite a Guest";
|
||||
if (is_numeric($id)) {
|
||||
$party = $this->Party->findById($id);
|
||||
if (empty($party['Party']['id']) ||
|
||||
$party['Party']['owner'] != $_SESSION['User']['id'] ||
|
||||
$party['Party']['canceled'] == 1)
|
||||
$this->redirect('/parties/view/all');
|
||||
|
||||
else {
|
||||
$this->set('partyid', $party['Party']['id']);
|
||||
$this->set('inviteurl', APP_BASE.'/parties/invited/'.$party['Party']['invitecode']);
|
||||
|
||||
$clean = new Sanitize();
|
||||
$uid = $clean->sql($_SESSION['User']['id']);
|
||||
$email = $this->Party->query("SELECT email FROM users WHERE id = ".$uid);
|
||||
|
||||
if (!empty($this->data)) {
|
||||
if ($this->Party->validates($this->data)) {
|
||||
$message = array('from' => APP_NAME.' <'.APP_EMAIL.'>',
|
||||
'envelope' => APP_EMAIL,
|
||||
'to' => $this->data['Party']['einvite'],
|
||||
'reply' => $email[0]['users']['email'],
|
||||
'subject' => 'You\'ve been invited to '.APP_NAME.'!',
|
||||
'link' => APP_BASE.'/parties/invited/'.$party['Party']['invitecode'],
|
||||
'type' => 'invite');
|
||||
|
||||
$this->Mail->mail($message);
|
||||
$this->Mail->send();
|
||||
|
||||
$this->Session->setFlash($this->data['Party']['einvite'].' has been
|
||||
invited. You can invite another guest below or <a href="'.APP_BASE.'/parties/view/'.$id.'/">click here</a>
|
||||
to return to your party.', 'infoFlash');
|
||||
$this->data['Party']['einvite'] = null;
|
||||
}
|
||||
else {
|
||||
$this->validateErrors($this->Party);
|
||||
$this->render();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function invited($icode = null, $conf = null) {
|
||||
$this->pageTitle = "Confirm Invite";
|
||||
if ($icode == 'cancel') {
|
||||
$this->Session->delete('invite');
|
||||
$this->Session->delete('invitestep');
|
||||
$this->redirect('/');
|
||||
}
|
||||
|
||||
else {
|
||||
$clean = new Sanitize();
|
||||
$icode = $clean->sql($icode);
|
||||
$party = $this->Party->findByInvitecode($icode);
|
||||
|
||||
if (empty($party['Party']['id'])) {
|
||||
$this->Session->setFlash('Could not find a party matching that invite code, please check it and try again.', 'errorFlash');
|
||||
}
|
||||
|
||||
else {
|
||||
if (!empty($_SESSION['User']['id']) && !empty($_SESSION['invitestep']) && $conf == 'confirm') {
|
||||
$this->Party->addGuest($_SESSION['User']['id'], $_SESSION['invite']);
|
||||
$this->Session->setFlash('You have been successfully added to this party.', 'infoFlash');
|
||||
$this->redirect('/parties/view/'.$party['Party']['id']);
|
||||
}
|
||||
|
||||
else if (!empty($_SESSION['User']['id'])) {
|
||||
$this->set('confirm_only', true);
|
||||
$this->set('party', $party);
|
||||
$this->set('icode', $icode);
|
||||
$this->Session->write('invitestep', 'true');
|
||||
$this->Session->write('invite', $icode);
|
||||
}
|
||||
|
||||
else {
|
||||
$this->Session->write('invite', $icode);
|
||||
$this->set('party', $party);
|
||||
$this->set('icode', $icode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function rsvp($pid) {
|
||||
if (is_numeric($pid) && isset($_SESSION['User']['id'])) {
|
||||
$party = $this->Party->findById($pid);
|
||||
if (empty($party['Party']['id'])) {
|
||||
$this->Session->setFlash('Invalid party id.', 'errorFlash');
|
||||
$this->redirect('/parties/view/all');
|
||||
}
|
||||
|
||||
else {
|
||||
if ($party['Party']['inviteonly']) {
|
||||
$this->Session->setFlash('This party invite only, you\'ll need an
|
||||
invitation from the host to join in', 'errorFlash');
|
||||
}
|
||||
|
||||
else {
|
||||
$this->Party->rsvp($pid, $_SESSION['User']['id']);
|
||||
$this->Session->setFlash('You have been successfully added to this party.', 'infoFlash');
|
||||
$this->redirect('/parties/view/'.$pid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
$this->redirect('/parties/view/all');
|
||||
}
|
||||
|
||||
function unrsvp($pid) {
|
||||
if (is_numeric($pid) && isset($_SESSION['User']['id'])) {
|
||||
$party = $this->Party->findById($pid);
|
||||
if (empty($party['Party']['id'])) {
|
||||
$this->Session->setFlash('Invalid party id.', 'errorFlash');
|
||||
$this->redirect('/parties/view/all');
|
||||
}
|
||||
|
||||
else {
|
||||
$this->Party->unrsvp($pid, $_SESSION['User']['id']);
|
||||
$this->Session->setFlash('You have been successfully removed from this party.', 'infoFlash');
|
||||
$this->redirect('/parties/view/'.$pid);
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
$this->redirect('/parties/view/all');
|
||||
}
|
||||
|
||||
function cancel($pid) {
|
||||
$this->pageTitle = "Cancel Party";
|
||||
if (!is_numeric($pid) || !isset($_SESSION['User']['id']))
|
||||
$this->redirect('/');
|
||||
|
||||
else
|
||||
$this->set('pid', $pid);
|
||||
|
||||
$party = $this->Party->findById($pid);
|
||||
if ($_SESSION['User']['id'] != $party['Party']['owner'])
|
||||
die();
|
||||
|
||||
if (!empty($this->data) && $_SESSION['User']['id'] == $party['Party']['owner']) {
|
||||
if ($this->data['Party']['confcancel'] == 1) {
|
||||
$guests = $this->Party->getGuests($pid);
|
||||
$guest_count = count($guests);
|
||||
|
||||
foreach($guests as $guest) {
|
||||
$message = array('from' => APP_NAME.' <'.APP_EMAIL.'>',
|
||||
'envelope' => APP_EMAIL,
|
||||
'to' => $guest['users']['email'],
|
||||
'reply' => $_SESSION['User']['email'],
|
||||
'subject' => 'Party Cancellation Notice',
|
||||
'link' => APP_BASE.'/parties/view/'.$pid,
|
||||
'type' => 'cancel');
|
||||
|
||||
$this->Mail->mail($message);
|
||||
$this->Mail->send();
|
||||
}
|
||||
|
||||
$this->Party->query("DELETE FROM guests WHERE pid = $pid LIMIT $guest_count");
|
||||
$this->Party->query("UPDATE parties SET canceled = '1', invitecode = '0' WHERE parties.id = $pid LIMIT 1");
|
||||
|
||||
$this->redirect('/parties/view/'.$pid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function uncancel($pid) {
|
||||
if (!is_numeric($pid) || !isset($_SESSION['User']['id']))
|
||||
$this->redirect('/');
|
||||
|
||||
$party = $this->Party->findById($pid);
|
||||
if ($_SESSION['User']['id'] != $party['Party']['owner'])
|
||||
die();
|
||||
|
||||
$key = $this->Hash->keygen(10);
|
||||
$this->Party->query("UPDATE parties SET canceled = '0', invitecode = '$key' WHERE parties.id = $pid LIMIT 1");
|
||||
$this->redirect('/parties/view/'.$pid);
|
||||
}
|
||||
|
||||
function js($type = null, $data = null) {
|
||||
$this->layout = 'ajax';
|
||||
|
||||
if ($type == 'html') {
|
||||
header('Content-type: text/plain');
|
||||
$party = $this->Party->findById($data);
|
||||
$this->set('party', $party);
|
||||
}
|
||||
|
||||
else {
|
||||
header('Content-type: text/javascript');
|
||||
$parties = $this->Party->findAll();
|
||||
$this->set('parties', $parties);
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -1,437 +0,0 @@
|
||||
<?php
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Party Tool
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Ryan Flint <rflint@dslr.net>
|
||||
* Portions created by the Initial Developer are Copyright (C) 2006
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
uses('sanitize');
|
||||
class UsersController extends AppController {
|
||||
var $name = 'Users';
|
||||
var $uses = array('User', 'Party');
|
||||
var $helpers = array('Html', 'Form');
|
||||
var $components = array('Security', 'Hash', 'Mail');
|
||||
|
||||
function index() {
|
||||
if (!isset($_SESSION['User'])) {
|
||||
$this->redirect('/users/login');
|
||||
}
|
||||
|
||||
$this->pageTitle = 'My Profile';
|
||||
|
||||
$user = $this->Session->read('User');
|
||||
$this->set('parties', $this->User->memberOf($user['id']));
|
||||
$this->set('hparties', $this->User->hostOf($user['id']));
|
||||
$this->set('iparties', $this->User->invitedTo($user['id']));
|
||||
}
|
||||
|
||||
function register() {
|
||||
$this->pageTitle = 'Register';
|
||||
$this->set('map', 'mapInit()');
|
||||
|
||||
if(empty($this->data)) {
|
||||
$this->set('utz', '0');
|
||||
$this->render();
|
||||
}
|
||||
|
||||
else {
|
||||
if ($this->User->findByEmail($this->data['User']['email']))
|
||||
$this->User->invalidate('email');
|
||||
|
||||
if ($this->data['User']['email'] !== $this->data['User']['confemail'])
|
||||
$this->User->invalidate('confemail');
|
||||
|
||||
if (!preg_match("/^(http|https)\:\/\//i", $this->data['User']['website']) &&
|
||||
!empty($this->data['User']['website']))
|
||||
$this->User->invalidate('website');
|
||||
|
||||
if ($this->data['User']['password'] !== $this->data['User']['confpass'])
|
||||
$this->User->invalidate('confpass');
|
||||
|
||||
if (empty($this->data['User']['password']) || empty($this->data['User']['confpass']))
|
||||
$this->User->invalidate('password');
|
||||
|
||||
// Repopulate the timezone with right value in case there's a validation error
|
||||
$this->set('utz', $this->data['User']['tz']);
|
||||
|
||||
if ($this->User->validates($this->data)) {
|
||||
$clean = new Sanitize();
|
||||
// Generate and set the password, salt and activation key
|
||||
$pass = $this->Hash->password($this->data['User']['password'],
|
||||
$this->data['User']['email']);
|
||||
$this->data['User']['active'] = $this->Hash->keygen(10);
|
||||
$this->data['User']['password'] = $pass['pass'];
|
||||
$this->data['User']['salt'] = $pass['salt'];
|
||||
|
||||
// Save a few fields from the wrath of cleanArray()
|
||||
$temp = array('lat' => $this->data['User']['lat'],
|
||||
'long' => $this->data['User']['long'],
|
||||
'tz' => $this->data['User']['tz'],
|
||||
'email' => $this->data['User']['email']);
|
||||
// Scrub 'a dub
|
||||
$clean->cleanArray($this->data);
|
||||
$this->data['User']['email'] = $temp['email'];
|
||||
$this->data['User']['long'] = floatval($temp['long']);
|
||||
$this->data['User']['lat'] = floatval($temp['lat']);
|
||||
$this->data['User']['tz'] = intval($temp['tz']);
|
||||
$this->data['User']['role'] = 0;
|
||||
|
||||
if($this->User->save($this->data)) {
|
||||
$message = array('from' => APP_NAME.' <'.APP_EMAIL.'>',
|
||||
'envelope' => APP_EMAIL,
|
||||
'to' => $this->data['User']['email'],
|
||||
'subject' => 'Your '.APP_NAME.' Registration',
|
||||
'link' => APP_BASE.'/users/activate/'.$this->data['User']['active'],
|
||||
'type' => 'act');
|
||||
$this->Mail->mail($message);
|
||||
$this->Mail->send();
|
||||
|
||||
if (isset($_SESSION['invite']))
|
||||
$this->Party->addGuest($this->User->getLastInsertId(), $_SESSION['invite']);
|
||||
|
||||
$this->Session->setFlash('Thank you for registering! To login, you\'ll
|
||||
need to activate your account. Please check
|
||||
your email for your activation link.', 'infoFlash');
|
||||
$this->redirect('/users/login');
|
||||
}
|
||||
|
||||
else {
|
||||
$this->data['User']['password'] = null;
|
||||
$this->data['User']['confpass'] = null;
|
||||
$this->render();
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
$this->data['User']['password'] = null;
|
||||
$this->data['User']['confpass'] = null;
|
||||
$this->Session->setFlash('There was an error in your submission. Please
|
||||
correct the errors shown below and try again.',
|
||||
'errorFlash');
|
||||
$this->render();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function edit() {
|
||||
if (!isset($_SESSION['User'])) {
|
||||
$this->redirect('/users/login');
|
||||
}
|
||||
$this->set('error', false);
|
||||
$this->pageTitle = 'Edit My Account';
|
||||
if (empty($this->data)) {
|
||||
$this->User->id = $_SESSION['User']['id'];
|
||||
$this->data = $this->User->read();
|
||||
$this->data['User']['password'] = "";
|
||||
$this->set('utz', $this->data['User']['tz']);
|
||||
|
||||
$this->data['User']['name'] = preg_replace("/&#(\d{2,5});/e",
|
||||
'$this->Unicode->unicode2utf(${1})',
|
||||
html_entity_decode($this->data['User']['name']));
|
||||
$this->data['User']['website'] = preg_replace("/&#(\d{2,5});/e",
|
||||
'$this->Unicode->unicode2utf(${1})',
|
||||
html_entity_decode($this->data['User']['website']));
|
||||
$this->data['User']['location'] = preg_replace("/&#(\d{2,5});/e",
|
||||
'$this->Unicode->unicode2utf(${1})',
|
||||
html_entity_decode($this->data['User']['location']));
|
||||
|
||||
if (GMAP_API_KEY != null) {
|
||||
if ($this->data['User']['lat'])
|
||||
$this->set('map', 'mapInit('.$this->data['User']['lat'].','.$this->data['User']['long'].','.$this->data['User']['zoom'].')');
|
||||
else
|
||||
$this->set('map', 'mapInit()');
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
$user = $this->User->findById($_SESSION['User']['id']);
|
||||
$this->User->id = $user['User']['id'];
|
||||
$this->set('utz', $user['User']['tz']);
|
||||
|
||||
$clean = new Sanitize();
|
||||
$temp = array('password' => $this->data['User']['password'],
|
||||
'confpassword' => $this->data['User']['confpassword'],
|
||||
'lat' => $clean->sql($this->data['User']['lat']),
|
||||
'long' => $clean->sql($this->data['User']['long']),
|
||||
'tz' => $clean->sql($this->data['User']['tz']));
|
||||
//Nuke everything else
|
||||
$clean->cleanArray($this->data);
|
||||
|
||||
$this->data['User']['email'] = $user['User']['email'];
|
||||
$this->data['User']['password'] = $temp['password'];
|
||||
$this->data['User']['confpassword'] = $temp['confpassword'];
|
||||
$this->data['User']['lat'] = floatval($temp['lat']);
|
||||
$this->data['User']['long'] = floatval($temp['long']);
|
||||
$this->data['User']['tz'] = intval($temp['tz']);
|
||||
$this->data['User']['role'] = $user['User']['role'];
|
||||
|
||||
if (!preg_match("/^(http|https)\:\/\//i", $this->data['User']['website']) &&
|
||||
!empty($this->data['User']['website']))
|
||||
$this->User->invalidate('website');
|
||||
|
||||
if ($this->data['User']['password'] === $this->data['User']['confpassword'] &&
|
||||
!empty($this->data['User']['password'])) {
|
||||
$pass = $this->Hash->password($this->data['User']['password'], $user['User']['email']);
|
||||
$this->data['User']['password'] = $pass['pass'];
|
||||
$this->data['User']['salt'] = $pass['salt'];
|
||||
}
|
||||
|
||||
else if (empty($this->data['User']['password']) && empty($this->data['User']['confpassword'])) {
|
||||
$this->data['User']['password'] = $user['User']['password'];
|
||||
$this->data['User']['salt'] = $user['User']['salt'];
|
||||
}
|
||||
|
||||
else {
|
||||
$this->set('error', true);
|
||||
$this->User->invalidate('password');
|
||||
$this->User->invalidate('confpassword');
|
||||
}
|
||||
|
||||
if ($this->User->validates($this->data)) {
|
||||
if ($this->User->save($this->data)) {
|
||||
$sess = $this->User->findById($user['User']['id']);
|
||||
$this->redirect('/users/');
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
$this->validateErrors($this->User);
|
||||
$this->data['User']['password'] = null;
|
||||
$this->data['User']['confpassword'] = null;
|
||||
$this->render();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function login() {
|
||||
if ($this->Session->Check('User'))
|
||||
$this->redirect('/users');
|
||||
|
||||
$this->pageTitle = 'Login';
|
||||
if (!empty($this->data)) {
|
||||
if (empty($this->data['User']['email']) || empty($this->data['User']['password']))
|
||||
$this->render();
|
||||
|
||||
$user = $this->User->findByEmail($this->data['User']['email']);
|
||||
$pass = sha1($this->data['User']['password'].$user['User']['salt']);
|
||||
|
||||
if ($user['User']['password'] == $pass) {
|
||||
if ($user['User']['active'] != 1) {
|
||||
$this->Session->setFlash('Your account hasn\'t been activated yet. Please
|
||||
check your email (including junk/spam folders)
|
||||
for your activation link, or click <a href="'
|
||||
.APP_BASE.'/users/recover/activate">here</a> to
|
||||
resend your activation details.', 'infoFlash');
|
||||
$this->render();
|
||||
}
|
||||
|
||||
else {
|
||||
if (isset($_SESSION['invite']))
|
||||
$this->Party->addGuest($user['User']['id'], $_SESSION['invite']);
|
||||
|
||||
$this->Session->write('User', $user['User']);
|
||||
$this->redirect('/users/');
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
$this->Session->setFlash('The email address and password you supplied do
|
||||
not match. Please try again.', 'errorFlash');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function view($id = null) {
|
||||
if (!is_numeric($id))
|
||||
$this->redirect('/');
|
||||
|
||||
else {
|
||||
$user = $this->User->findById($id);
|
||||
$this->pageTitle = $user['User']['name'];
|
||||
$this->set('user', $user);
|
||||
if (GMAP_API_KEY != null && !empty($user['User']['lat']))
|
||||
$this->set('map', 'mapInit('.$user['User']['lat'].','.$user['User']['long'].','.$user['User']['zoom'].',\'stationary\');');
|
||||
|
||||
$this->Party->unbindModel(array('hasMany' => array('Comment')));
|
||||
$this->set('hparties', $this->User->hostOf($id));
|
||||
$att = $this->User->query('SELECT parties.id, parties.name
|
||||
FROM parties
|
||||
LEFT JOIN guests
|
||||
ON parties.id = guests.pid
|
||||
WHERE guests.uid = '.$id);
|
||||
$this->set('parties', $att);
|
||||
}
|
||||
}
|
||||
|
||||
function logout() {
|
||||
$this->Session->destroy();
|
||||
$this->Session->delete('User');
|
||||
$this->redirect('/');
|
||||
}
|
||||
|
||||
function recover($aType = null, $aCode = null, $aId = null) {
|
||||
switch ($aType) {
|
||||
case "password":
|
||||
$this->pageTitle = "Password Recovery";
|
||||
$this->set('atitle', 'Password Recovery');
|
||||
$this->set('hideInput', false);
|
||||
$this->set('url', 'password');
|
||||
|
||||
if (!empty($this->data)) {
|
||||
$user = $this->User->findByEmail($this->data['User']['email']);
|
||||
|
||||
if (!isset($user['User']['email'])) {
|
||||
$this->Session->setFlash('Could not find a user with that email address. Please check it and try again.', 'errorFlash');
|
||||
$this->render();
|
||||
}
|
||||
else {
|
||||
$code = md5($user['User']['salt'].$user['User']['email'].$user['User']['password']);
|
||||
$message = array('from' => APP_NAME.' <'.APP_EMAIL.'>',
|
||||
'envelope' => APP_EMAIL,
|
||||
'to' => $user['User']['email'],
|
||||
'subject' => APP_NAME.' Password Request',
|
||||
'link' => APP_BASE.'/users/recover/password/'.$code.'/'.$user['User']['id'],
|
||||
'type' => 'prec');
|
||||
|
||||
$this->Mail->mail($message);
|
||||
$this->Mail->send();
|
||||
$this->Session->setFlash('An email has been sent to '.$user['User']['email'].' with reset instructions.', 'errorFlash');
|
||||
$this->redirect('users/login');
|
||||
}
|
||||
}
|
||||
|
||||
if ($aCode !== null && $aId !== null) {
|
||||
$this->set('hideInput', true);
|
||||
$this->set('reset', false);
|
||||
$user = $this->User->findById($aId);
|
||||
|
||||
if (!$user) {
|
||||
$this->Session->setFlash('Invalid request. Please check the URL and try again.', 'errorFlash');
|
||||
$this->render();
|
||||
}
|
||||
|
||||
if ($aCode == md5($user['User']['salt'].$user['User']['email'].$user['User']['password'])) {
|
||||
$this->set('reset', true);
|
||||
$this->set('code', $aCode."/".$aId);
|
||||
$this->render();
|
||||
}
|
||||
|
||||
else {
|
||||
$this->Session->setFlash('Invalid request. Please check the URL and try again.', 'errorFlash');
|
||||
$this->render();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "activate":
|
||||
$this->pageTitle = 'Resend Activation Code';
|
||||
$this->set('atitle', 'Resend Activation Code');
|
||||
$this->set('hideInput', false);
|
||||
$this->set('url', 'activate');
|
||||
|
||||
if (!empty($this->data)) {
|
||||
$user = $this->User->findByEmail($this->data['User']['email']);
|
||||
|
||||
if (!$user) {
|
||||
$this->Session->setFlash('Could not find a user with that email address. Please check it and try again.', 'errorFlash');
|
||||
$this->render();
|
||||
}
|
||||
|
||||
if ($user['User']['active'] == 1)
|
||||
$this->redirect('/users/login');
|
||||
|
||||
else {
|
||||
$message = array('from' => APP_NAME.' <'.APP_EMAIL.'>',
|
||||
'envelope' => APP_EMAIL,
|
||||
'to' => $this->data['User']['email'],
|
||||
'subject' => 'Your '.APP_NAME.' Registration',
|
||||
'link' => APP_BASE.'/users/activate/'.$user['User']['active'],
|
||||
'type' => 'act');
|
||||
$this->Mail->mail($message);
|
||||
$this->Mail->send();
|
||||
$this->Session->setFlash('Your activation code has been resent.', 'infoFlash');
|
||||
$this->redirect('users/login');
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "reset":
|
||||
if ($aCode !== null && $aId !== null) {
|
||||
if (!empty($this->data)) {
|
||||
$user = $this->User->findById($aId);
|
||||
if (!$user) {
|
||||
$this->Session->setFlash('Invalid request. Please check the URL and try again.', 'errorFlash');
|
||||
$this->render();
|
||||
}
|
||||
|
||||
if ($aCode == md5($user['User']['salt'].$user['User']['email'].$user['User']['password'])) {
|
||||
$string = $user['User']['email'] . uniqid(rand(), true) . $this->data['User']['password'];
|
||||
$this->data['User']['salt'] = substr(md5($string), 0, 9);
|
||||
$this->data['User']['password'] = sha1($this->data['User']['password'] . $this->data['User']['salt']);
|
||||
$this->data['User']['id'] = $aId;
|
||||
if ($this->User->save($this->data)) {
|
||||
$this->Session->setFlash('Your password has been reset.', 'infoFlash');
|
||||
$this->redirect('/users/login');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$this->redirect('/');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function activate($aKey = null) {
|
||||
if ($aKey == null)
|
||||
$this->redirect('/');
|
||||
|
||||
else {
|
||||
$user = $this->User->findByActive($aKey);
|
||||
if (empty($user['User']['id'])) {
|
||||
$this->Session->setFlash('Your account could not be activated. Please make
|
||||
sure the URL entered is correct and try again.', 'errorFlash');
|
||||
$this->redirect('/users/login');
|
||||
}
|
||||
|
||||
else {
|
||||
$this->data = $user;
|
||||
$this->data['User']['active'] = 1;
|
||||
|
||||
if ($this->User->save($this->data)) {
|
||||
$this->Session->setFlash('Your account was successfully activated.', 'infoFlash');
|
||||
$this->redirect('/users/login');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -1,26 +0,0 @@
|
||||
<?php
|
||||
/* SVN FILE: $Id: index.php,v 1.3 2006-10-08 03:39:21 reed%reedloden.com Exp $ */
|
||||
/**
|
||||
* PHP versions 4 and 5
|
||||
*
|
||||
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
|
||||
* Copyright (c) 2006, Cake Software Foundation, Inc.
|
||||
* 1785 E. Sahara Avenue, Suite 490-204
|
||||
* Las Vegas, Nevada 89104
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @filesource
|
||||
* @copyright Copyright (c) 2006, Cake Software Foundation, Inc.
|
||||
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
|
||||
* @package cake
|
||||
* @subpackage cake.app
|
||||
* @since CakePHP v 0.10.0.1076
|
||||
* @version $Revision: 1.3 $
|
||||
* @modifiedby $LastChangedBy: phpnut $
|
||||
* @lastmodified $Date: 2006-10-08 03:39:21 $
|
||||
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
||||
*/
|
||||
require 'webroot' . DIRECTORY_SEPARATOR . 'index.php';
|
||||
?>
|
||||
@@ -1,41 +0,0 @@
|
||||
<?php
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Party Tool
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Ryan Flint <rflint@dslr.net>
|
||||
* Portions created by the Initial Developer are Copyright (C) 2006
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
class Admin extends AppModel {
|
||||
var $name = 'Admin';
|
||||
var $useTable = "parties";
|
||||
}
|
||||
?>
|
||||
@@ -1,61 +0,0 @@
|
||||
<?php
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Party Tool
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Ryan Flint <rflint@dslr.net>
|
||||
* Portions created by the Initial Developer are Copyright (C) 2006
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
class Comment extends AppModel {
|
||||
var $name = 'Comment';
|
||||
|
||||
var $validate = array(
|
||||
'text' => "/^\S/"
|
||||
);
|
||||
|
||||
function canComment($pid, $uid) {
|
||||
$status = $this->query('SELECT owner, guestcomments FROM parties WHERE id = '.$pid);
|
||||
$guest = null;
|
||||
if ($status[0]['parties']['owner'] != $uid)
|
||||
$guest = $this->query('SELECT uid FROM guests WHERE pid = '.$pid.' AND uid = '.$uid);
|
||||
|
||||
if ($status[0]['parties']['guestcomments'] == 1) {
|
||||
if (!empty($guest[0]['guests']['uid']) || $uid == $status[0]['parties']['owner'])
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
else
|
||||
return true;
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -1,51 +0,0 @@
|
||||
<?php
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Party Tool
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Ryan Flint <rflint@dslr.net>
|
||||
* Portions created by the Initial Developer are Copyright (C) 2006
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
class Feed extends AppModel {
|
||||
var $name = 'Feeds';
|
||||
var $useTable = "parties";
|
||||
|
||||
function getComments($aParty) {
|
||||
$rv = $this->query("SELECT * FROM comments WHERE assoc = ".$aParty." LIMIT 10");
|
||||
return $rv;
|
||||
}
|
||||
|
||||
function getUserCount() {
|
||||
$rv = $this->query("SELECT COUNT(*) FROM users");
|
||||
return $rv[0][0]['COUNT(*)'];
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -1,40 +0,0 @@
|
||||
<?php
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Party Tool
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Ryan Flint <rflint@dslr.net>
|
||||
* Portions created by the Initial Developer are Copyright (C) 2006
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
class Guest extends AppModel {
|
||||
var $name = 'Guest';
|
||||
}
|
||||
?>
|
||||
@@ -1,46 +0,0 @@
|
||||
<?php
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Party Tool
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Ryan Flint <rflint@dslr.net>
|
||||
* Portions created by the Initial Developer are Copyright (C) 2006
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
class Page extends AppModel {
|
||||
var $name = 'Page';
|
||||
var $useTable = 'parties';
|
||||
|
||||
function getUsers() {
|
||||
$rv = $this->query("SELECT COUNT(*) FROM users");
|
||||
return $rv[0][0]["COUNT(*)"];
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -1,110 +0,0 @@
|
||||
<?php
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Party Tool
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Ryan Flint <rflint@dslr.net>
|
||||
* Portions created by the Initial Developer are Copyright (C) 2006
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
class Party extends AppModel {
|
||||
var $name = 'Party';
|
||||
var $validate = array(
|
||||
'name' => "/^\S/",
|
||||
'einvite' => VALID_EMAIL,
|
||||
'duration' => VALID_NUMBER
|
||||
);
|
||||
|
||||
function getComments($pid) {
|
||||
$rv = $this->query("SELECT users.id AS uid, users.name,
|
||||
comments.id AS cid, comments.time, comments.text
|
||||
FROM users, parties, comments
|
||||
WHERE comments.assoc = ".$pid."
|
||||
AND users.id = comments.owner
|
||||
AND parties.id = ".$pid."
|
||||
ORDER BY cid ASC");
|
||||
return $rv;
|
||||
}
|
||||
|
||||
function getHost($uid) {
|
||||
$rv = $this->query("SELECT name FROM users WHERE id = ".$uid);
|
||||
return @$rv[0]['users']['name'];
|
||||
}
|
||||
|
||||
function isGuest($pid, $uid) {
|
||||
$rv = $this->query('SELECT id FROM guests WHERE uid = '.$uid.' AND pid = '.$pid);
|
||||
if (!empty($rv[0]['guests']['id']))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
function getGuests($pid) {
|
||||
$rv = $this->query("SELECT users.id, users.name, users.email, guests.invited
|
||||
FROM users
|
||||
LEFT JOIN guests
|
||||
ON users.id = guests.uid
|
||||
WHERE guests.pid = ".$pid);
|
||||
return $rv;
|
||||
}
|
||||
|
||||
function rsvp($pid, $uid) {
|
||||
$party = $this->findById($pid);
|
||||
if (!empty($party['Party']['id']) && !$this->isGuest($pid, $uid)) {
|
||||
$this->query("INSERT INTO guests (id, pid, uid, invited)
|
||||
VALUES (NULL, ".$party['Party']['id'].", ".$uid.", 0)");
|
||||
}
|
||||
}
|
||||
|
||||
function unrsvp($pid, $uid) {
|
||||
$party = $this->findById($pid);
|
||||
if (!empty($party['Party']['id']) && $this->isGuest($pid, $uid)) {
|
||||
$this->query('DELETE FROM guests WHERE uid = '.$uid.' AND pid = '.$pid);
|
||||
}
|
||||
}
|
||||
|
||||
function addGuest($uid, $icode) {
|
||||
$party = $this->findByInvitecode($icode);
|
||||
if (!empty($party['Party']['id'])) {
|
||||
$check = $this->query('SELECT uid FROM guests WHERE uid = '.$uid.'
|
||||
AND pid = '.$party['Party']['id']);
|
||||
if (empty($check[0]['guests']['uid']) && $uid != $party['Party']['owner']) {
|
||||
$this->query("INSERT INTO guests (id, pid, uid, invited)
|
||||
VALUES (NULL, ".$party['Party']['id'].", ".$uid.", 1)");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function findByInvitecode($icode) {
|
||||
$rv = $this->query('SELECT * FROM parties AS Party WHERE invitecode = "'.$icode.'" LIMIT 1');
|
||||
return @$rv[0];
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -1,59 +0,0 @@
|
||||
<?php
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Party Tool
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Ryan Flint <rflint@dslr.net>
|
||||
* Portions created by the Initial Developer are Copyright (C) 2006
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
class User extends AppModel {
|
||||
var $name = 'User';
|
||||
var $validate = array(
|
||||
'email' => VALID_EMAIL,
|
||||
'name' => "/^\S/"
|
||||
);
|
||||
|
||||
function memberOf($uid) {
|
||||
$rv = $this->query('SELECT parties.id, parties.name FROM guests, parties WHERE guests.uid = '.$uid.' AND parties.id = guests.pid');
|
||||
return $rv;
|
||||
}
|
||||
|
||||
function hostOf($uid) {
|
||||
$rv = $this->query('SELECT id, name FROM parties WHERE owner = '.$uid);
|
||||
return $rv;
|
||||
}
|
||||
|
||||
function invitedTo($uid) {
|
||||
$rv = $this->query('SELECT parties.id, parties.name FROM guests, parties WHERE guests.uid = '.$uid.' AND parties.id = guests.pid AND guests.invited = 1');
|
||||
return $rv;
|
||||
}
|
||||
}
|
||||
?>
|
||||
199
mozilla/webtools/partytool/vendors/webServices.php
vendored
199
mozilla/webtools/partytool/vendors/webServices.php
vendored
@@ -1,199 +0,0 @@
|
||||
<?php
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Party Tool
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Ryan Flint <rflint@dslr.net>
|
||||
* Portions created by the Initial Developer are Copyright (C) 2006
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
class webServices {
|
||||
|
||||
var $userid;
|
||||
var $host;
|
||||
var $randomize;
|
||||
|
||||
function webServices($data) {
|
||||
switch ($data['type']) {
|
||||
case "flickr":
|
||||
$this->host = "api.flickr.com";
|
||||
|
||||
if (array_key_exists('userid', $data))
|
||||
$this->userid = $data['userid'];
|
||||
|
||||
if (array_key_exists('randomize', $data))
|
||||
$this->randomize = $data['randomize'];
|
||||
|
||||
if (array_key_exists('username', $data)) {
|
||||
$head = "GET /services/rest/?method=flickr.people.findByUsername&api_key=".FLICKR_API_KEY."&username=".$data['username']." HTTP/1.1\r\n";
|
||||
$head .= "Host: ".$this->host."\r\n";
|
||||
$head .= "Connection: Close\r\n\r\n";
|
||||
|
||||
if ($results = $this->fetchResults($head)) {
|
||||
preg_match('/nsid=\"(.*)\"/', $results, $matches);
|
||||
if ($matches[1]) {
|
||||
$this->userid = $matches[1];
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case "gsuggest":
|
||||
$this->host = "api.google.com";
|
||||
break;
|
||||
|
||||
case "geocode":
|
||||
$this->host = "maps.google.com";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function getFlickrId() {
|
||||
return $this->userid;
|
||||
}
|
||||
|
||||
function fetchPhotos($tags, $num_results, $single_user) {
|
||||
$params = array('api_key' => FLICKR_API_KEY,
|
||||
'method' => 'flickr.photos.search',
|
||||
'format' => 'php_serial',
|
||||
'tags' => $tags,
|
||||
'per_page' => $num_results);
|
||||
|
||||
if ($single_user)
|
||||
$params['user_id'] = $this->userid;
|
||||
|
||||
$encoded_params = array();
|
||||
foreach ($params as $k => $v)
|
||||
$encoded_params[] = urlencode($k).'='.urlencode($v);
|
||||
|
||||
$head = 'GET /services/rest/?'.implode('&', $encoded_params)." HTTP/1.1 \r\n";
|
||||
$head .= 'Host: '.$this->host."\r\n";
|
||||
$head .= "Connection: Close\r\n\r\n";
|
||||
|
||||
if ($results = $this->fetchResults($head)) {
|
||||
$resp = split("\r\n\r\n", $results);
|
||||
$data = unserialize($resp[1]);
|
||||
|
||||
if ($data['stat'] == 'ok') {
|
||||
$arr = array();
|
||||
for ($i = 0; $i < count($data['photos']['photo']); $i++) {
|
||||
$p = $data['photos']['photo'][$i];
|
||||
$arr[$i] = array('id' => $p['id'],
|
||||
'owner' => $p['owner'],
|
||||
'secret' => $p['secret'],
|
||||
'server' => $p['server'],
|
||||
'farm' => $p['farm'],
|
||||
'title' => $p['title']);
|
||||
}
|
||||
|
||||
if ($this->randomize) {
|
||||
// Randomize the results
|
||||
shuffle($arr);
|
||||
}
|
||||
|
||||
return $arr;
|
||||
}
|
||||
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
function GSuggest($phrase) {
|
||||
$soapy = '<?xml version=\'1.0\' encoding=\'UTF-8\'?>
|
||||
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
|
||||
xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
|
||||
xmlns:xsd="http://www.w3.org/1999/XMLSchema">
|
||||
<SOAP-ENV:Body>
|
||||
<doSpellingSuggestion xmlns="urn:GoogleSearch">
|
||||
<key xsi:type="xsd:string">'.GSEARCH_API_KEY.'</key>
|
||||
<phrase xsi:type="xsd:string">'.$phrase.'</phrase>
|
||||
</doSpellingSuggestion>
|
||||
</SOAP-ENV:Body>
|
||||
</SOAP-ENV:Envelope>';
|
||||
|
||||
$head = "POST /search/beta2 HTTP/1.1\r\n";
|
||||
$head .= "Host: api.google.com\r\n";
|
||||
$head .= "MessageType: CALL\r\n";
|
||||
$head .= "Content-type: text/xml\r\n";
|
||||
$head .= "Content-length: ".strlen($soapy)."\r\n";
|
||||
$head .= "Connection: Close\r\n\r\n";
|
||||
$head .= $soapy;
|
||||
|
||||
if ($results = $this->fetchResults($head)) {
|
||||
if (preg_match('/return xsi:type="xsd:string">(.*)</', $results, $matches))
|
||||
return $matches[1];
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
function geocode($query) {
|
||||
$head = "GET /maps/geo?q=".urlencode($query)."&output=xml&key=".GMAP_API_KEY." HTTP/1.1\r\n";
|
||||
$head .= "Host: maps.google.com\r\n";
|
||||
$head .= "Connection: Close\r\n\r\n";
|
||||
|
||||
if ($results = $this->fetchResults($head)) {
|
||||
if (stristr($results, '<code>200</code>')) {
|
||||
preg_match('/coordinates>(.*)</', $results, $matches);
|
||||
$ll = explode(',', $matches[1]);
|
||||
$rv = array('lat' => $ll[1], 'lng' => $ll[0]);
|
||||
return $rv;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
function fetchResults($headers) {
|
||||
$fs = fsockopen($this->host, 80, $errno, $errstr, 30);
|
||||
if (!$fs)
|
||||
return 0;
|
||||
|
||||
else {
|
||||
fwrite($fs, $headers);
|
||||
stream_set_timeout($fs, 2);
|
||||
|
||||
$buffer = null;
|
||||
while (!feof($fs))
|
||||
$buffer .= fgets($fs, 128);
|
||||
|
||||
fclose($fs);
|
||||
|
||||
return $buffer;
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
||||
@@ -1,18 +0,0 @@
|
||||
<h1>Comments</h1>
|
||||
<p>Switch view to: <a href="<?php echo $html->url('/admin/'); ?>">Parties»</a> <a href="<?php echo $html->url('/admin/users'); ?>">Users»</a></p>
|
||||
<table>
|
||||
<tr>
|
||||
<td>ID</td>
|
||||
<td>Text</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<?php foreach($comments as $comment): ?>
|
||||
<tr>
|
||||
<td><a href="<?php echo $html->url('/parties/view/'.$comment['Comment']['assoc'].'#c'.$comment['Comment']['id']); ?>"><?php echo $comment['Comment']['id']; ?></a></td>
|
||||
<td><?php echo $comment['Comment']['text']; ?></td>
|
||||
<td><a href="<?php echo $html->url('/admin/edit/comment/'.$comment['Comment']['id']); ?>">Edit</a></td>
|
||||
<td><a href="<?php echo $html->url('/admin/delete/comment/'.$comment['Comment']['id']); ?>" onclick="return confirm('Delete comment <?php echo $comment['Comment']['id']; ?>?')">Delete</a></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</table>
|
||||
@@ -1,128 +0,0 @@
|
||||
<?php if (isset($user)): ?>
|
||||
<h1><?php echo $user['User']['name'].' (<a href="'.$html->url('/users/view/'.$user['User']['id']).'">'.$user['User']['id']; ?></a>)</h1>
|
||||
<form class="fxform" action="<?php echo $html->url('/admin/edit/user/'.$user['User']['id']); ?>" method="post">
|
||||
<div>
|
||||
<label for="UserName" class="label-large">Name:</label>
|
||||
<?php echo $html->input('User/name', array('size' => 40)); ?>
|
||||
</div>
|
||||
<div>
|
||||
<label for="UserRole" class="label-large">Admin privileges:</label>
|
||||
<?php echo $html->checkbox('User/role'); ?>
|
||||
</div>
|
||||
<div>
|
||||
<label for="UserEmail" class="label-large">Email address:</label>
|
||||
<?php echo $html->input('User/email', array('size' => 40)); ?>
|
||||
</div>
|
||||
<div>
|
||||
<label for="UserWebsite" class="label-large">Website:</label>
|
||||
<?php echo $html->input('User/website', array('size' => 40)); ?>
|
||||
</div>
|
||||
<div>
|
||||
<label for="UserActive" class="label-large">Activation code:</label>
|
||||
<?php echo $html->input('User/active', array('size' => 40)); ?>
|
||||
</div>
|
||||
<div>
|
||||
<label for="location" class="label-large">Location:</label>
|
||||
<?php echo $html->input('User/location', array('size' => 40)); ?>
|
||||
</div>
|
||||
<div>
|
||||
<label for="UserShowemail" class="label-large">Show email:</label>
|
||||
<?php echo $html->checkbox('User/showemail'); ?><br/>
|
||||
</div>
|
||||
<div>
|
||||
<label for="UserShowloc" class="label-large">Show location:</label>
|
||||
<?php echo $html->checkbox('User/showloc'); ?><br/>
|
||||
</div>
|
||||
<div>
|
||||
<label for="UserShowmap" class="label-large">Show map:</label>
|
||||
<?php echo $html->checkbox('User/showmap'); ?><br/>
|
||||
</div>
|
||||
<?php echo $html->hidden('User/id', array('value' => $user['User']['id'])).$html->submit('Submit'); ?>
|
||||
</form>
|
||||
|
||||
<?php endif; if (isset($party)): ?>
|
||||
<h1><?php echo $party['Party']['name'].' (<a href="'.$html->url('/parties/view/'.$party['Party']['id']).'">'.$party['Party']['id']; ?></a>)</h1>
|
||||
<form class="fxform" action="<?php echo $html->url('/admin/edit/party/'.$party['Party']['id']); ?>" method="post">
|
||||
<div>
|
||||
<label for="PartyOwner" class="label-large">Party Owner:</label>
|
||||
<?php echo $html->input('Party/owner', array('size' => 40)); ?>
|
||||
</div>
|
||||
<div>
|
||||
<label for="PartyName" class="label-large">Party Name:</label>
|
||||
<?php echo $html->input('Party/name', array('size' => 40)); ?>
|
||||
</div>
|
||||
<div>
|
||||
<label for="PartyVname" class="label-large">Venue Name:</label>
|
||||
<?php echo $html->input('Party/vname', array('size' => 40)); ?>
|
||||
</div>
|
||||
<div>
|
||||
<label for="PartyWebsite" class="label-large">Web site:</label>
|
||||
<?php echo $html->input('Party/website', array('size' => 40)); ?>
|
||||
</div>
|
||||
<div>
|
||||
<label for="PartyAddress" class="label-large">Address:</label>
|
||||
<?php echo $html->input('Party/address', array('size' => 40)); ?>
|
||||
</div>
|
||||
<div>
|
||||
<label for="PartyDate" class="label-large">Date:</label>
|
||||
<?php echo $html->input('Party/date', array('size' => 40)); ?>
|
||||
</div>
|
||||
<div>
|
||||
<label for="PartyNotes" class="label-large">Additional Notes:</label>
|
||||
<?php echo $html->textarea('Party/notes', array('rows' => 10, 'cols' => 50)); ?>
|
||||
</div>
|
||||
<div>
|
||||
<label for="PartyConfirmed" class="label-large">Time:</label>
|
||||
<?php echo $html->radio('Party/confirmed', array(0 => 'Tentative', 1 => 'Confirmed')); ?>
|
||||
</div>
|
||||
<div>
|
||||
<label for="PartyDuration" class="label-large">Duration (in hours):</label>
|
||||
<?php echo $html->input('Party/duration', array('size' => 5)); ?>
|
||||
</div>
|
||||
<div>
|
||||
<label for="PartyCanceled" class="label-large">Canceled:</label>
|
||||
<?php echo $html->checkbox('Party/canceled'); ?>
|
||||
</div>
|
||||
<div>
|
||||
<label for="PartyUseflickr" class="label-large">Use Flickr:</label>
|
||||
<?php echo $html->checkbox('Party/useflickr'); ?>
|
||||
</div>
|
||||
<div>
|
||||
<label for="PartyFlickrperms" class="label-large">Show:</label>
|
||||
<?php echo $html->radio('Party/flickrperms', array(0 => 'Only my photos', 1 => 'Anyone\'s photos')); ?>
|
||||
</div>
|
||||
<div>
|
||||
<label for="PartyFlickrusr" class="label-large">Flickr username:</label>
|
||||
<?php echo $html->input('Party/flickrusr', array('size' => 40)); ?>
|
||||
</div>
|
||||
<div>
|
||||
<label for="PartyFlickrusr" class="label-large">Flickr id:</label>
|
||||
<?php echo $html->input('Party/flickrid', array('size' => 40)); ?>
|
||||
</div>
|
||||
<div>
|
||||
<label for="PartyInviteonly" class="label-large">Invite only:</label>
|
||||
<?php echo $html->checkbox('Party/inviteonly'); ?>
|
||||
</div>
|
||||
<div>
|
||||
<label for="PartyGuestcomments" class="label-large">Limit comments to party guests only:</label>
|
||||
<?php echo $html->checkbox('Party/guestcomments'); ?>
|
||||
</div>
|
||||
<br/>
|
||||
<?php echo $html->hidden('Party/id', array('value' => $party['Party']['id'])).$html->submit('Submit'); ?>
|
||||
</form>
|
||||
|
||||
<?php endif; if(isset($comment)): ?>
|
||||
<h1>Comment <?php echo '<a href="'.$html->url('/parties/view/'.$comment['Comment']['assoc'].'#c'.$comment['Comment']['id']).'">#'.$comment['Comment']['id']; ?></a> by <?php echo '<a href="'.$html->url('/users/view/'.$comment['Comment']['owner']).'">'.$owner; ?></a></h1>
|
||||
<form class="fxform" action="<?php echo $html->url('/admin/edit/comment/'.$comment['Comment']['id']); ?>" method="post">
|
||||
<div>
|
||||
<label for="CommentAssoc" class="label-large">Party:</label>
|
||||
<?php echo $html->input('Comment/assoc', array('size' => 40)); ?>
|
||||
</div>
|
||||
<div>
|
||||
<label for="CommentText" class="label-large">Text:</label>
|
||||
<?php echo $html->textarea('Comment/text', array('rows' => 10, 'cols' => 50)); ?>
|
||||
</div>
|
||||
<?php echo $html->hidden('Comment/id', array('value' => $comment['Comment']['id'])).$html->submit('Submit'); ?>
|
||||
</form>
|
||||
|
||||
<?php endif; ?>
|
||||
@@ -1,18 +0,0 @@
|
||||
<h1>Parties</h1>
|
||||
<p>Switch view to: <a href="<?php echo $html->url('/admin/users'); ?>">Users»</a> <a href="<?php echo $html->url('/admin/comments'); ?>">Comments»</a></p>
|
||||
<table>
|
||||
<tr>
|
||||
<td>ID</td>
|
||||
<td>Name</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<?php foreach($parties as $party): ?>
|
||||
<tr>
|
||||
<td><a href="<?php echo $html->url('/parties/view/'.$party['Party']['id']); ?>"><?php echo $party['Party']['id']; ?></a></td>
|
||||
<td><?php echo $party['Party']['name']; ?></td>
|
||||
<td><a href="<?php echo $html->url('/admin/edit/party/'.$party['Party']['id']); ?>">Edit</a></td>
|
||||
<td><a href="<?php echo $html->url('/admin/delete/party/'.$party['Party']['id']); ?>" onclick="return confirm('Delete party <?php echo $party['Party']['id']; ?>?')">Delete</a></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</table>
|
||||
@@ -1,18 +0,0 @@
|
||||
<h1>Users</h1>
|
||||
<p>Switch view to: <a href="<?php echo $html->url('/admin/'); ?>">Parties»</a> <a href="<?php echo $html->url('/admin/comments'); ?>">Comments»</a></p>
|
||||
<table>
|
||||
<tr>
|
||||
<td>ID</td>
|
||||
<td>Name</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<?php foreach($users as $user): ?>
|
||||
<tr>
|
||||
<td><a href="<?php echo $html->url('/users/view/'.$user['User']['id']); ?>"><?php echo $user['User']['id']; ?></a></td>
|
||||
<td><?php echo $user['User']['name']; ?></td>
|
||||
<td><a href="<?php echo $html->url('/admin/edit/user/'.$user['User']['id']); ?>">Edit</a></td>
|
||||
<td><a href="<?php echo $html->url('/admin/delete/user/'.$user['User']['id']); ?>" onclick="return confirm('Delete user <?php echo $user['User']['id']; ?>?')">Delete</a></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</table>
|
||||
@@ -1,7 +0,0 @@
|
||||
<?php if(!isset($_SESSION['User'])): ?>
|
||||
<strong>Welcome, Guest!</strong>
|
||||
<a href="<?php echo $html->url('/users/login'); ?>">Login</a> | <a href="<?php echo $html->url('/users/register'); ?>">Register</a>
|
||||
<?php else: ?>
|
||||
<strong>Welcome, <?php echo $_SESSION['User']['name']; ?>!</strong>
|
||||
<a href="<?php echo $html->url('/users'); ?>">My Account</a> | <a href="<?php echo $html->url('/users/logout'); ?>">Logout</a>
|
||||
<?php endif; ?>
|
||||
@@ -1,16 +0,0 @@
|
||||
<?php echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"; ?>
|
||||
<rss version="0.91">
|
||||
<channel>
|
||||
<pubDate><?php echo date('r'); ?></pubDate>
|
||||
<description><?php echo APP_NAME." - Latest Comments"; ?></description>
|
||||
<link><?php echo APP_BASE.$html->url('/parties/view/'.$pid); ?></link>
|
||||
<title><?php echo APP_NAME." - Latest Comments"; ?></title>
|
||||
<?php foreach($comments as $comment): ?>
|
||||
<item>
|
||||
<title><![CDATA[<?php echo substr($comment['comments']['text'], 0, 25).'...'; ?>]]></title>
|
||||
<description><?php echo $comment['comments']['text'] ?></description>
|
||||
<link><?php echo APP_BASE.$html->url('/parties/view/'.$comment['comments']['assoc'].'#c'.$comment['comments']['id']); ?></link>
|
||||
</item>
|
||||
<?php endforeach; ?>
|
||||
</channel>
|
||||
</rss>
|
||||
@@ -1,22 +0,0 @@
|
||||
BEGIN:VCALENDAR
|
||||
X-WR-CALNAME:<?php echo APP_NAME."\n"; ?>
|
||||
X-WR-CALDESC:Upcoming Parties
|
||||
PRODID:-//MozillaPartyTool//calendar//EN
|
||||
VERSION:2.0
|
||||
CALSCALE:GREGORIAN
|
||||
METHOD:PUBLISH
|
||||
<?php foreach($events as $event):
|
||||
if ($event['Feeds']['canceled']) continue; ?>
|
||||
BEGIN:VEVENT
|
||||
UID:<?php echo APP_BASE.$html->url('/parties/view/'.$event['Feeds']['id'])."\n"; ?>
|
||||
DTSTAMP:<?php echo gmdate('Ymd\This\Z', $event['Feeds']['date'])."\n"; ?>
|
||||
LOCATION:<?php echo $event['Feeds']['lat'].'\, '.$event['Feeds']['long'].'('.$event['Feeds']['address'].")\n"; ?>
|
||||
SUMMARY:<?php echo $event['Feeds']['name']."\n"; ?>
|
||||
DTSTART:<?php echo gmdate('Ymd\This', $event['Feeds']['date'])."\n"; ?>
|
||||
DURATION:PT<?php echo $event['Feeds']['duration']; ?>H
|
||||
URL:<?php echo APP_BASE.$html->url('/parties/view/'.$event['Feeds']['id'])."\n"; ?>
|
||||
STATUS:<?php echo (($event['Feeds']['confirmed'] == 1) ? "CONFIRMED" : "TENTATIVE")."\n"; ?>
|
||||
DESCRIPTION: <?php echo $event['Feeds']['name'].'\n '.$event['Feeds']['address'].'\n '.date('h:ia', $event['Feeds']['date']).'\n '.$event['Feeds']['notes'].'\n'."\n"; ?>
|
||||
END:VEVENT
|
||||
<?php endforeach; ?>
|
||||
END:VCALENDAR
|
||||
@@ -1,14 +0,0 @@
|
||||
<?php echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"; ?>
|
||||
<rss version="0.91">
|
||||
<channel>
|
||||
<pubDate><?php echo date('r'); ?></pubDate>
|
||||
<description><?php echo APP_NAME." - Party Count"; ?></description>
|
||||
<link><?php echo APP_BASE.$html->url('/'); ?></link>
|
||||
<title><?php echo APP_NAME." - Party Count"; ?></title>
|
||||
<item>
|
||||
<title><?php echo $count; ?></title>
|
||||
<description>Total Parties</description>
|
||||
<link><?php echo APP_BASE.$html->url('/parties/view/all/'); ?></link>
|
||||
</item>
|
||||
</channel>
|
||||
</rss>
|
||||
@@ -1,17 +0,0 @@
|
||||
<?php echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"; ?>
|
||||
<rss version="0.91">
|
||||
<channel>
|
||||
<pubDate><?php echo date('r'); ?></pubDate>
|
||||
<description><?php echo APP_NAME." - Latest Parties"; ?></description>
|
||||
<link><?php echo APP_BASE.$html->url('/'); ?></link>
|
||||
<title><?php echo APP_NAME." - Latest Parties"; ?></title>
|
||||
<?php foreach($latest as $party):
|
||||
if ($party['Feeds']['canceled']) continue; ?>
|
||||
<item>
|
||||
<title><?php echo $party['Feeds']['name'] ?></title>
|
||||
<description><?php echo $party['Feeds']['vname'] ?></description>
|
||||
<link><?php echo APP_BASE.$html->url('/parties/view/'.$party['Feeds']['id']); ?></link>
|
||||
</item>
|
||||
<?php endforeach; ?>
|
||||
</channel>
|
||||
</rss>
|
||||
@@ -1,23 +0,0 @@
|
||||
<?php echo '<?xml version="1.0" encoding="utf-8"?>'."\n"; ?>
|
||||
<feed xmlns="http://www.w3.org/2005/Atom">
|
||||
<title><?php echo $party['Feeds']['name']; ?></title>
|
||||
<id>tag:<?php echo APP_BASE; ?>,2006:/parties/view/<?php echo $party['Feeds']['id']; ?></id>
|
||||
<subtitle><?php echo APP_NAME; ?> Photostream</subtitle>
|
||||
<updated><?php echo date('Y-m-d\TH:i:s\Z'); ?></updated>
|
||||
<generator uri="http://www.screwedbydesign.com/software/partytool">Mozilla Party Tool</generator>
|
||||
|
||||
<?php foreach ($flickr as $pic): ?>
|
||||
<entry>
|
||||
<title><?php echo $pic['title']; ?></title>
|
||||
<link rel="alternate" type="text/html" href="http://www.flickr.com/photos/<?php echo $pic['owner']."/".$pic['id']."/"; ?>"/>
|
||||
<id>tag:flickr.com,2005:/photo/<?php echo $pic['id']; ?></id>
|
||||
<published><?php echo date('Y-m-d\TH:i:s\Z'); ?></published>
|
||||
<updated><?php echo date('Y-m-d\TH:i:s\Z'); ?></updated>
|
||||
<content type="html"><a href="http://www.flickr.com/photos/<?php echo $pic['owner']."/".$pic['id']."/" ?>"> <img src="http://static.flickr.com/<?php echo $pic['server']."/".$pic['id']."_".$pic['secret']."_m.jpg" ?>" title="<?php echo $pic['title']; ?>"/></a></content>
|
||||
<author>
|
||||
<name><?php echo $pic['owner']; ?></name>
|
||||
<uri>http://www.flickr.com/people/<?php echo $pic['owner']; ?>/</uri>
|
||||
</author>
|
||||
</entry>
|
||||
<?php endforeach; ?>
|
||||
</feed>
|
||||
@@ -1,16 +0,0 @@
|
||||
<?php echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"; ?>
|
||||
<rss version="0.91">
|
||||
<channel>
|
||||
<pubDate><?php echo date('r'); ?></pubDate>
|
||||
<description><?php echo APP_NAME." - Top Guests"; ?></description>
|
||||
<link><?php echo APP_BASE.$html->url('/parties/view/all'); ?></link>
|
||||
<title><?php echo APP_NAME." - Top Guests"; ?></title>
|
||||
<?php foreach($items as $item):?>
|
||||
<item>
|
||||
<title><?php echo $item['parties']['name'].' ('.$item[0]['count'].')'; ?></title>
|
||||
<description><?php echo $item['parties']['name'].' - '.$item[0]['count'].' guest'.(($item[0]['count'] != 1) ? 's' : ''); ?></description>
|
||||
<link><?php echo APP_BASE.$html->url('/parties/view/'.$item['guests']['id']); ?></link>
|
||||
</item>
|
||||
<?php endforeach; ?>
|
||||
</channel>
|
||||
</rss>
|
||||
@@ -1,17 +0,0 @@
|
||||
<?php echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"; ?>
|
||||
<rss version="0.91">
|
||||
<channel>
|
||||
<pubDate><?php echo date('r'); ?></pubDate>
|
||||
<description><?php echo APP_NAME." - Upcoming Parties"; ?></description>
|
||||
<link><?php echo APP_BASE.$html->url('/'); ?></link>
|
||||
<title><?php echo APP_NAME." - Upcoming Parties"; ?></title>
|
||||
<?php foreach($latest as $party):
|
||||
if ($party['Feeds']['canceled']) continue; ?>
|
||||
<item>
|
||||
<title><![CDATA[<?php echo $party['Feeds']['name'] ?>]]></title>
|
||||
<description><?php echo date('Y-m-d H:i', $party['Feeds']['date']); ?></description>
|
||||
<link><?php echo APP_BASE.$html->url('/parties/view/'.$party['Feeds']['id']); ?></link>
|
||||
</item>
|
||||
<?php endforeach; ?>
|
||||
</channel>
|
||||
</rss>
|
||||
@@ -1,14 +0,0 @@
|
||||
<?php echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"; ?>
|
||||
<rss version="0.91">
|
||||
<channel>
|
||||
<pubDate><?php echo date('r'); ?></pubDate>
|
||||
<description><?php echo APP_NAME." - Total Users"; ?></description>
|
||||
<link><?php echo APP_BASE.$html->url('/'); ?></link>
|
||||
<title><?php echo APP_NAME." - Total Users"; ?></title>
|
||||
<item>
|
||||
<title><?php echo $count; ?></title>
|
||||
<description>Total Users</description>
|
||||
<link><?php echo APP_BASE.$html->url('/'); ?></link>
|
||||
</item>
|
||||
</channel>
|
||||
</rss>
|
||||
@@ -1,40 +0,0 @@
|
||||
<?php echo '<?xml version="1.0" encoding="UTF-8"?>'; ?>
|
||||
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title><?php echo APP_NAME." - ".$title_for_layout?></title>
|
||||
<link rel="shortcut icon" type="image/x-icon" href="<?php echo $html->url('/favicon.ico'); ?>"/>
|
||||
<link rel="stylesheet" type="text/css" href="<?php echo $html->url('/css/main.css'); ?>"/>
|
||||
<link rel="alternate" type="application/rss+xml" href="<?php echo $html->url('/feeds/latest'); ?>"/>
|
||||
</head>
|
||||
<body<?php echo (isset($map)) ? ' onload="'.$map.'" onunload="GUnload()"' : '';?>>
|
||||
<div id="container">
|
||||
<p class="skipLink"><a href="#content" accesskey="2">Skip to main content</a></p>
|
||||
<div id="mozilla-com"><a href="http://www.mozilla.com/">Visit Mozilla.com</a></div>
|
||||
<div id="header">
|
||||
<div id="key-title">
|
||||
<h1><a href="<?php echo $html->url('/'); ?>" title="Return to home page" accesskey="1"><img src="<?php echo $html->url('/img/firefox-title.png'); ?>" width="276" height="54" alt="Firefox Party"/></a></h1>
|
||||
<div id="user"><?php echo $this->renderElement('user_options'); ?></div>
|
||||
</div>
|
||||
<div id="key-menu">
|
||||
<ul id="menu-firefox">
|
||||
<li<?php echo (@$current == 'home') ? ' class="current"' : ''?>><a href="<?php echo $html->url('/'); ?>">Home</a></li>
|
||||
<li<?php echo (@$current == 'map') ? ' class="current"' : ''?>><a href="<?php echo $html->url('/parties/'); ?>">View Map</a></li>
|
||||
<li<?php echo (@$current == 'parties') ? ' class="current"' : ''?>><a href="<?php echo $html->url('/parties/view/all/'); ?>">View Parties</a></li>
|
||||
<li<?php echo (@$current == 'create') ? ' class="current"' : ''?>><a href="<?php echo $html->url('/parties/add/'); ?>">Create Party</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div id="content">
|
||||
<?php $this->controller->Session->flash(); ?>
|
||||
|
||||
<?php echo $content_for_layout; ?>
|
||||
</div>
|
||||
<div id="footer">
|
||||
Copyright © <?php echo date('Y'); ?> Mozilla<br/>
|
||||
<a href="<?php echo $html->url('/privacy-policy'); ?>">Privacy Policy</a>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1 +0,0 @@
|
||||
<div id='flash' class='error'><?php echo $content_for_layout ?></div>
|
||||
@@ -1 +0,0 @@
|
||||
<div id='flash' class='info'><?php echo $content_for_layout ?></div>
|
||||
@@ -1,30 +0,0 @@
|
||||
<?php
|
||||
$difference = $time - time();
|
||||
$days_left = floor($difference/60/60/24);
|
||||
?>
|
||||
<div id="f-left">
|
||||
<?php echo $front_text;
|
||||
if (@$_SESSION['User']['role'] == 1): ?>
|
||||
<a href="<?php echo $html->url('/pages/edit'); ?>">Edit</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div id="f-right">
|
||||
<div class="cbox">
|
||||
<span class="ctxt"><?php echo $pcount."</span><br/>".(($pcount == 1) ? ' Party' : ' Parties'); ?>
|
||||
<div class="ifeed">
|
||||
<a style="padding-right: 2px;" title="Party Calendar" href="<?php echo $html->url('/feeds/ical'); ?>"><img src="<?php echo $html->url('/img/ical.png'); ?>" alt="iCAL"/></a><a title="Party Count Feed" href="<?php echo $html->url('/feeds/'); ?>"><img src="<?php echo $html->url('/img/feed16.png'); ?>" alt="RSS"/></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cbox">
|
||||
<span class="ctxt"><?php echo $ucount."</span><br/>".(($ucount == 1) ? ' Partygoer' : ' Partygoers'); ?>
|
||||
<div class="cfeed">
|
||||
<a title="User Count Feed" href="<?php echo $html->url('/feeds/users/'); ?>"><img src="<?php echo $html->url('/img/feed16.png'); ?>" alt="RSS"/></a>
|
||||
</div>
|
||||
</div>
|
||||
<?php if ($days_left > 0): ?>
|
||||
<div class="cbox">
|
||||
<span class="ctxt"><?php echo $days_left."</span><br/>".(($days_left == 1) ? ' Day' : ' Days'); ?> until we party!
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div style="clear: both"></div>
|
||||
@@ -1,6 +0,0 @@
|
||||
<form action="<?php echo $html->url('/pages/edit'); ?>" method="post">
|
||||
<h1>Front Page Text</h1>
|
||||
<?php echo $html->textarea('Pages/text', array('rows' => 35, 'cols' => 80)); ?>
|
||||
<h1>Countdown Timer</h1>
|
||||
<?php echo $html->dateTimeOptionTag('Pages/date', 'YMD', 24, $selected).'<br/><br/>'.$html->submit('Submit'); ?>
|
||||
</form>
|
||||
@@ -1,42 +0,0 @@
|
||||
<h2>Mozilla Privacy Policy</h2>
|
||||
|
||||
<h3>Website Visitors</h3>
|
||||
|
||||
<p>Except as described below, the Mozilla Foundation and the Mozilla Corporation (collectively "Mozilla") do not collect or require visitors to its Web sites to furnish personally-identifying information such as names, email addresses and phone numbers. Like most Web site operators, Mozilla does collect non-personally-identifying information of the sort that web browsers and servers typically make available, such as the browser type, language preference, referring site, and date and time of each visitor request. Mozilla also collects potentially personally-identifying information like Internet Protocol (IP) addresses, which are non-personally-identifying in and of themselves but could be used in conjunction with other information to personally identify users.</p>
|
||||
|
||||
<p>Mozilla's purpose in collecting this information is to better understand how Mozilla's visitors use its Web sites. To that end, Mozilla may share potentially personally-identifying information with its employees, contractors and affiliated organizations. Mozilla may also release non-personally-identifying information about visitors, e.g. by publishing a report on Web site usage trends. Otherwise, Mozilla will not publicly release potentially personally-identifying information except under the same circumstances as Mozilla releases personally-identifying information. Those circumstances are explained in detail below.</p>
|
||||
|
||||
<h3>Community Members</h3>
|
||||
|
||||
<p>Certain members of the Mozilla community (contributors, customers, etc.) choose to interact with Mozilla in ways that require Mozilla and others to know more about them. The amount and type of information that Mozilla gathers from those members depends on the nature of the interaction. For example, members who wish to post content to certain portions of Mozilla's Web sites are asked to provide usernames that identify that content as having been posted by a particular member. Developers, by comparison, are asked to provide contact information, up to and sometimes including telephone or fax numbers, so that they can be contacted as necessary. Customers of the Mozilla store are asked to provide even more information, including billing and shipping addresses and credit card or similar information. In each case, Mozilla collects personally-identifying information only insofar as is necessary to fulfill the purpose of the community member's interaction with Mozilla.</p>
|
||||
|
||||
<p>Mozilla is an open organization that believes in sharing as much information as possible about its products, its operations and its associations. Accordingly, community members should assume - as should most folks who interact with Mozilla - that any personally-identifying information provided to Mozilla will be made available to the public. There are three broad exceptions to that rule:</p>
|
||||
|
||||
<ol>
|
||||
|
||||
<li>Mozilla does not publicly release information gathered in connection with commercial transactions (i.e., transactions involving money), including transactions conducted through the Mozilla Store.</li>
|
||||
<li>Mozilla does not make publicly available information that is used to authenticate users the publication of which would compromise the security of Mozilla's Web sites (e.g., passwords).</li>
|
||||
<li>Mozilla does not make publicly available information that it specifically promises at the time of collection to maintain in confidence.</li>
|
||||
</ol>
|
||||
|
||||
<p>Outside those three contexts, users should assume that personally-identifying information provided through Mozilla's Web sites will be made available to the public.</p>
|
||||
|
||||
<h3>Interactive Product Features</h3>
|
||||
|
||||
<p>Certain Mozilla products contain features that report, or that permit users to report, the user's usage patterns and problems - whether caused by Mozilla's software, third party software, or third-party Web sites - to Mozilla. The reports generated by these features typically include non-personally-identifying information such as the configuration of the user's computer and the code running at the time the problem occurred. Some of these features give users the option of providing personally-identifying information, though none of these features require it. Some Mozilla software features that do permit users to provide personally-identifying information advise in advance that such information will not be made publicly available. Mozilla analyzes the information provided by these interactive product features to develop a better understanding of how its products are performing and being used. It does not use the information to track the usage of its products by identifiable individuals.</p>
|
||||
|
||||
<h3>Cookies</h3>
|
||||
|
||||
<p>A cookie is a string of information that a Web site stores on a visitor's computer, and that the visitor's browser provides to the Web site each time the visitor returns. Mozilla's Web sites use cookies to help Mozilla identify and track visitors, their usage of Mozilla Web sites, and their Web site access preferences across multiple requests and visits to Mozilla's Web sites. It is possible to link cookies to personally-identifying information, thereby permitting Web site operators to track the online movements of particular individuals. Mozilla, however, does not do so. Instead, it uses the information provided by cookies to develop a better understanding of how Mozilla's visitors use, and to facilitate those visitors' interactions with, Mozilla's Web sites. Mozilla visitors who do not wish to have cookies placed on their computers by Mozilla or its contractors should set their browsers to refuse cookies before linking to Mozilla's Web sites. Certain features of Mozilla's Web sites may not function properly without the aid of cookies.</p>
|
||||
|
||||
<h3>Protection of Certain Personally-Identifying Information</h3>
|
||||
|
||||
<p>Where Mozilla has collected personally-identifying information subject to one of the three exceptions described in the Contributors and Customers section, above, it discloses that information only to those of its employees, contractors and affiliated organizations that need to know that information in order to process it on Mozilla's behalf and that have agreed not to disclose it to others. Some of those employees, contractors and affiliated organizations may be located outside of your home country; by using Mozilla's Web sites, you consent to the transfer of your information to them. Mozilla does not rent or sell such information to anyone. Other than to its employees, contractors and affiliated organizations, as described above, Mozilla discloses such information only when required to do so by law, or when Mozilla believes in good faith that disclosure is reasonably necessary to protect the property or rights of Mozilla, members of the Mozilla community, or the public at large. Mozilla takes all measures reasonably necessary to protect against the unauthorized access, use, alteration or destruction of such information</p>
|
||||
|
||||
<h3>Updating of Personally-Identifying Information</h3>
|
||||
|
||||
<p>Mozilla permits users to freely update and correct their personally-identifying information as maintained by Mozilla. To do so, users need only look for the links and other tools available on Mozilla's Web sites or contact Mozilla by email.</p>
|
||||
|
||||
<h3>Privacy Policy Changes</h3>
|
||||
|
||||
<p>Although changes are likely to be minor, Mozilla may change its Privacy Policy from time to time. Any and all changes will be reflected on this page. Substantive changes will also be announced through the standard mechanisms through which Mozilla communicates with the Mozilla community, including Mozilla's "mozilla-announce" mailing lists.</p>
|
||||
@@ -1,109 +0,0 @@
|
||||
<h1>Create a Party</h1>
|
||||
<form class="fxform" action="<?php echo $html->url('/parties/add'); ?>" method="post">
|
||||
<div>
|
||||
<label for="PartyName" class="label-large">Party Name<span class="required">*</span>:</label>
|
||||
<?php echo $html->input('Party/name', array('size' => 40)); ?>
|
||||
<?php echo $html->tagErrorMsg('Party/name', 'Please enter a party name.')?>
|
||||
</div>
|
||||
<div>
|
||||
<label for="PartyVname" class="label-large">Venue Name:</label>
|
||||
<?php echo $html->input('Party/vname', array('size' => 40)); ?>
|
||||
</div>
|
||||
<div>
|
||||
<label for="PartyAddress" class="label-large">Address:</label>
|
||||
<?php echo $html->input('Party/address', array('size' => 40, 'id' => 'location', 'onkeypress' => 'capture(event)', 'onblur' => 'update()')); ?>
|
||||
<div id="locerr" class="info" style="display: none">Did you mean: <a id="locerrlink" onclick="geocode_suggest()" href="#"></a>? <a href="#" onclick="shide()"><span style="font-size: x-small">(close)</span></a></div>
|
||||
</div>
|
||||
<p>Enter your party's time and date (in your local time) here. If you're not ready to commit to a specific time or date, select the 'Tentative'
|
||||
radio button. Otherwise select 'Confirmed'.</p>
|
||||
<div>
|
||||
<label for="PartyYear" class="label-large">Date:</label>
|
||||
<?php echo $html->yearOptionTag('Party/year', null, date('Y'), MAX_YEAR, date('Y'), null, null, false); ?>-<?php echo $html->hourOptionTag('Party/month', null, false, date('m')); ?>-<?php echo $html->dayOptionTag('Party/day', null, date('d'), null, false); ?>
|
||||
</div>
|
||||
<div>
|
||||
<label for="PartyHour" class="label-large">Time:</label>
|
||||
<?php echo $html->hourOptionTag('Party/hour', null, true);?>:<?php echo $html->minuteOptionTag('Party/minute');?>
|
||||
<?php echo $html->radio('Party/confirmed', array(0 => 'Tentative', 1 => 'Confirmed')); ?><br/>
|
||||
</div>
|
||||
<p>The timezone is used to calculate the appropriate GMT time from the local time specified above. This is done to show
|
||||
the party in the local time of the person viewing it.</p>
|
||||
<div>
|
||||
<label for="PartyTz" class="label-large">Timezone<span class="required">*</span>:</label>
|
||||
<?php
|
||||
$tzs = array('-12' => 'GMT-12',
|
||||
'-11' => 'GMT-11',
|
||||
'-10' => 'GMT-10',
|
||||
'-9' => 'GMT-9',
|
||||
'-8' => 'GMT-8',
|
||||
'-7' => 'GMT-7',
|
||||
'-6' => 'GMT-6',
|
||||
'-5' => 'GMT-5',
|
||||
'-4' => 'GMT-4',
|
||||
'-3' => 'GMT-3',
|
||||
'-2' => 'GMT-2',
|
||||
'-1' => 'GMT-1',
|
||||
'0' => 'GMT+0',
|
||||
'1' => 'GMT+1',
|
||||
'2' => 'GMT+2',
|
||||
'3' => 'GMT+3',
|
||||
'4' => 'GMT+4',
|
||||
'5' => 'GMT+5',
|
||||
'6' => 'GMT+6',
|
||||
'7' => 'GMT+7',
|
||||
'8' => 'GMT+8',
|
||||
'9' => 'GMT+9',
|
||||
'10' => 'GMT+10',
|
||||
'11' => 'GMT+11',
|
||||
'12' => 'GMT+12',
|
||||
'13' => 'GMT+13');
|
||||
echo $html->selectTag('Party/tz', $tzs, $utz, null, null, false);
|
||||
?>
|
||||
(this page was loaded at <?php echo gmdate("Y-m-d H:i:s"); ?> GMT)
|
||||
</div>
|
||||
<div>
|
||||
<label for="PartyDuration" class="label-large">Duration (in hours):</label>
|
||||
<?php echo $html->input('Party/duration', array('size' => 5)); ?>
|
||||
</div>
|
||||
<p>Enter a website (complete with http://) that guests can visit to learn more about your party. If you don't have one, simply leave it blank.</p>
|
||||
<div>
|
||||
<label for="PartyWebsite" class="label-large">Web site:</label>
|
||||
<?php echo $html->input('Party/website', array('size' => 40)); ?>
|
||||
<?php echo $html->tagErrorMsg('Party/website', 'Invalid URL.')?>
|
||||
</div>
|
||||
<p>If you choose to make your party invite only, you will have to send guests an invite containing a random invite code to allow them to join your party.</p>
|
||||
<div>
|
||||
<label for="PartyInviteonly" class="label-large">Invite only</label>
|
||||
<?php echo $html->checkbox('Party/inviteonly'); ?>
|
||||
</div>
|
||||
<?php if(GMAP_API_KEY != null): ?>
|
||||
<script src="http://maps.google.com/maps?file=api&v=2&key=<?php echo GMAP_API_KEY; ?>"
|
||||
type="text/javascript"></script>
|
||||
<script src="<?php echo $html->url('/js/maps.js'); ?>" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
function update() {
|
||||
var loc = document.getElementById("location").value;
|
||||
geocode(loc);
|
||||
}
|
||||
|
||||
function capture(event) {
|
||||
if (event.keyCode == 13) {
|
||||
event.preventDefault();
|
||||
update();
|
||||
}
|
||||
}
|
||||
//]]>
|
||||
</script>
|
||||
<p>Drag the map or the marker to specify a location. Set the zoom by using the '+' or '-' buttons on the left.</p>
|
||||
<p id="map" class="med-map-r"></p>
|
||||
<?php echo $html->hidden('Party/lat', array('id' => 'lat'));
|
||||
echo $html->hidden('Party/long', array('id' => 'long'));
|
||||
echo $html->hidden('Party/zoom', array('id' => 'zoom'));
|
||||
echo $html->hidden('Party/geocoded', array('id' => 'geocoded', 'value' => 0)); ?>
|
||||
<?php endif; ?>
|
||||
<div>
|
||||
<label for="PartyNotes" class="label-large">Additional Notes</label>
|
||||
<?php echo $html->textarea('Party/notes', array('rows' => 10, 'cols' => 50)); ?>
|
||||
</div>
|
||||
<?php echo $html->submit('Create Party'); ?>
|
||||
</form>
|
||||
@@ -1,7 +0,0 @@
|
||||
<h1>Cancel Party</h1>
|
||||
<div class="error">Warning! Canceling your party will remove all guests and send them a cancellation notice.</div>
|
||||
<p>If you're sure you want to cancel your party simply hit the button below. Otherwise,
|
||||
<a href="<?php echo $html->url('/parties/view/'.$pid); ?>">click here</a> to return to your party.</p>
|
||||
<form action="<?php echo $html->url('/parties/cancel/'.$pid); ?>" method="post">
|
||||
<?php echo $html->hidden('Party/confcancel', array('value' => 1)).$html->submit('Cancel Party'); ?>
|
||||
</form>
|
||||
@@ -1,131 +0,0 @@
|
||||
<form class="fxform" action="<?php echo $html->url('/parties/edit/'.$party['Party']['id']); ?>" method="post">
|
||||
<?php echo $html->hidden('Party/id'); ?>
|
||||
<h1>Details</h1>
|
||||
<div>
|
||||
<label for="PartyName" class="label-large">Party Name:</label>
|
||||
<?php echo $html->input('Party/name', array('size' => 40)); ?>
|
||||
</div>
|
||||
<div>
|
||||
<label for="PartyVname" class="label-large">Venue Name:</label>
|
||||
<?php echo $html->input('Party/vname', array('size' => 40)); ?>
|
||||
</div>
|
||||
<div>
|
||||
<label for="PartyWebsite" class="label-large">Web site:</label>
|
||||
<?php echo $html->input('Party/website', array('size' => 40)); ?>
|
||||
<?php echo $html->tagErrorMsg('Party/website', 'Invalid URL.')?>
|
||||
</div>
|
||||
<div>
|
||||
<label for="PartyAddress" class="label-large">Address:</label>
|
||||
<?php echo $html->input('Party/address', array('size' => 40, 'id' => 'location', 'onkeypress' => 'capture(event)', 'onblur' => 'update()')); ?>
|
||||
<div id="suggest" style="display: none">Did you mean <span style="font-style: italic"><a id="suggest2" href="#" onclick=""></a></span>?</div>
|
||||
</div>
|
||||
<?php if(GMAP_API_KEY != null): ?>
|
||||
<script src="http://maps.google.com/maps?file=api&v=2&key=<?php echo GMAP_API_KEY; ?>"
|
||||
type="text/javascript"></script>
|
||||
<script src="<?php echo $html->url('/js/maps.js'); ?>" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
|
||||
//<![CDATA[
|
||||
function update(aSuggest) {
|
||||
var loc;
|
||||
if (!aSuggest)
|
||||
loc = document.getElementById("location").value;
|
||||
else
|
||||
loc = aSuggest;
|
||||
|
||||
if (loc != "")
|
||||
geocode(loc);
|
||||
}
|
||||
|
||||
function capture(event) {
|
||||
if (event.keyCode == 13) {
|
||||
event.preventDefault();
|
||||
update();
|
||||
}
|
||||
}
|
||||
//]]>
|
||||
</script>
|
||||
<p id="map" class="med-map-r"></p>
|
||||
<div>
|
||||
<label for="PartyNotes" class="label-large">Additional Notes:</label>
|
||||
<?php echo $html->textarea('Party/notes', array('rows' => 10, 'cols' => 50)); ?>
|
||||
</div>
|
||||
<h1>Date</h1>
|
||||
<div>
|
||||
<label for="PartyYear" class="label-large">Date:</label>
|
||||
<?php echo $html->yearOptionTag('Party/year', null, date('Y'), MAX_YEAR, $date['year'], null, null, false); ?>-<?php echo $html->hourOptionTag('Party/month', null, false, $date['mon']); ?>-<?php echo $html->dayOptionTag('Party/day', null, $date['day'], null, false); ?>
|
||||
</div>
|
||||
<div>
|
||||
<label for="PartyHour" class="label-large">Time:</label>
|
||||
<?php echo $html->hourOptionTag('Party/hour', null, true, $date['hour']);?>:<?php echo $html->minuteOptionTag('Party/minute', null, $date['min']);?>
|
||||
<?php echo $html->radio('Party/confirmed', array(0 => 'Tentative', 1 => 'Confirmed')); ?>
|
||||
</div>
|
||||
<div>
|
||||
<label for="PartyTz" class="label-large">Timezone:</label>
|
||||
<?php
|
||||
$tzs = array('-12' => 'GMT-12',
|
||||
'-11' => 'GMT-11',
|
||||
'-10' => 'GMT-10',
|
||||
'-9' => 'GMT-9',
|
||||
'-8' => 'GMT-8',
|
||||
'-7' => 'GMT-7',
|
||||
'-6' => 'GMT-6',
|
||||
'-5' => 'GMT-5',
|
||||
'-4' => 'GMT-4',
|
||||
'-3' => 'GMT-3',
|
||||
'-2' => 'GMT-2',
|
||||
'-1' => 'GMT-1',
|
||||
'0' => 'GMT+0',
|
||||
'1' => 'GMT+1',
|
||||
'2' => 'GMT+2',
|
||||
'3' => 'GMT+3',
|
||||
'4' => 'GMT+4',
|
||||
'5' => 'GMT+5',
|
||||
'6' => 'GMT+6',
|
||||
'7' => 'GMT+7',
|
||||
'8' => 'GMT+8',
|
||||
'9' => 'GMT+9',
|
||||
'10' => 'GMT+10',
|
||||
'11' => 'GMT+11',
|
||||
'12' => 'GMT+12',
|
||||
'13' => 'GMT+13');
|
||||
|
||||
echo $html->selectTag('Party/tz', $tzs, $date['tz'], null, null, false);?>
|
||||
(current time is <?php echo gmdate("Y-m-d H:i:s"); ?>GMT)
|
||||
</div>
|
||||
<div>
|
||||
<label for="PartyDuration" class="label-large">Duration (in hours):</label>
|
||||
<?php echo $html->input('Party/duration', array('size' => 5)); ?>
|
||||
</div>
|
||||
<h1><span style="color: #0063dc">flick</span><span style="color: #ff0084">r<sup style="font-size: 8px">TM</sup></span> Options</h1>
|
||||
<p>To show photos of your party, simply tag them with <strong><?php echo FLICKR_TAG_PREFIX.$party['Party']['id'] ?></strong> and fill out the information below.</p>
|
||||
<div>
|
||||
<label for="PartyUseflickr" class="label-large">Show photostream:</label>
|
||||
<?php echo $html->checkbox('Party/useflickr'); ?>
|
||||
</div>
|
||||
<p>If you choose to show photos from anyone using your party's tag please note that no photos will show until two or more people are using the tag.</p>
|
||||
<div>
|
||||
<label for="PartyFlickrperms" class="label-large">Show:</label>
|
||||
<?php echo $html->radio('Party/flickrperms', array(0 => 'Only my photos', 1 => 'Anyone\'s photos')); ?>
|
||||
</div>
|
||||
<div>
|
||||
<label for="PartyFlickrusr" class="label-large">Flickr username:</label>
|
||||
<?php echo $html->input('Party/flickrusr', array('size' => 40)); ?>
|
||||
</div>
|
||||
<h1>Privacy</h1>
|
||||
<div>
|
||||
<label for="PartyInviteonly" class="label-large">Invite only:</label>
|
||||
<?php echo $html->checkbox('Party/inviteonly'); ?>
|
||||
</div>
|
||||
<div>
|
||||
<label for="PartyGuestcomments" class="label-large">Limit comments to party guests only:</label>
|
||||
<?php echo $html->checkbox('Party/guestcomments'); ?>
|
||||
</div>
|
||||
<br/>
|
||||
<?php echo $html->hidden('Party/lat', array('id' => 'lat'));
|
||||
echo $html->hidden('Party/long', array('id' => 'long'));
|
||||
echo $html->hidden('Party/zoom', array('id' => 'zoom'));
|
||||
echo $html->hidden('Party/geocoded', array('id' => 'geocoded', 'value' => 0)); ?>
|
||||
<?php endif; ?>
|
||||
<?php echo $html->submit('Update'); ?>
|
||||
</form>
|
||||
@@ -1,19 +0,0 @@
|
||||
<?php if(GMAP_API_KEY != null): ?>
|
||||
<div style="text-align: center">
|
||||
<form action="<?php echo $html->url('/parties/'); ?>" class="fxform" onsubmit="search(event)" method="post">
|
||||
<label for="PartyMloc"><strong>Find a party:</strong></label>
|
||||
<?php echo $html->input('Party/mloc', array('size' => 60, 'id' => 'location')).' '.$html->submit('Search'); ?>
|
||||
<div id="locerr" class="info" style="display: none">Did you mean: <a id="locerrlink" onclick="geocode_suggest()" href="#"></a>? <a href="#" onclick="shide()"><span style="font-size: x-small">(close)</span></a></div>
|
||||
</form>
|
||||
</div>
|
||||
<br/>
|
||||
<script src="http://maps.google.com/maps?file=api&v=2.67&key=<?php echo GMAP_API_KEY; ?>"
|
||||
type="text/javascript"></script>
|
||||
<script src="<?php echo $html->url('/js/maps.js'); ?>" type="text/javascript"></script>
|
||||
<script src="<?php echo $html->url('/parties/js'); ?>" type="text/javascript"></script>
|
||||
<div id="map" class="large-map"></div>
|
||||
<div id="map-load" style="visibility: hidden" class="load">
|
||||
<img src="<?php echo $html->url('/img/throbber.gif'); ?>"/>
|
||||
Loading...
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
@@ -1,9 +0,0 @@
|
||||
<h1>Invite a guest</h1>
|
||||
<p>To invite a guest, simply enter their email address into the field below,
|
||||
or hand them a link to
|
||||
<strong><?php echo $inviteurl; ?></strong></p>
|
||||
<form action="<?php echo $html->url('/parties/invite/'.$partyid) ?>" method="post">
|
||||
<label for="PartyEinvite">Guest's email address:</label>
|
||||
<?php echo $html->input('Party/einvite')."\n".$html->submit('Submit')."\n"; ?>
|
||||
<?php echo $html->tagErrorMsg('Party/einvite', 'Invalid email address')?>
|
||||
</form>
|
||||
@@ -1,36 +0,0 @@
|
||||
<h1>Confirm Invite</h1>
|
||||
<?php if (isset($party) && !isset($confirm_only)): ?>
|
||||
<p>You've been invited to attend <a href="<?php echo $html->url('/parties/view/'.$party['Party']['id']); ?>"><?php echo $party['Party']['name']; ?></a>.
|
||||
To join this party please select one of the options below, or <a href="<?php echo $html->url('/parties/invited/cancel/');?>">click here</a> to cancel this invitation.</p>
|
||||
<div style="text-align: center">
|
||||
<div style="width: 50%; float: left;">
|
||||
<h2>New User</h2>
|
||||
<p>Simply register for an account, and you'll be added as a guest as soon as you finish.
|
||||
<a href="<?php echo $html->url('/users/register'); ?>">Create account »</a></p>
|
||||
</div>
|
||||
<div style="width: 50%; float: right">
|
||||
<h2>Existing User</h2>
|
||||
<p>Login to add yourself to the guest list.</p>
|
||||
<form class="fxform" action="<?php echo $html->url('/users/login'); ?>" method="post">
|
||||
<div>
|
||||
<label class="label-large" for="UserEmail">Email Address:</label>
|
||||
<?php echo $html->input('User/email', array('size' => 20)); ?>
|
||||
</div>
|
||||
<div>
|
||||
<label class="label-large" for="UserPassword">Password:</label>
|
||||
<?php echo $html->password('User/password', array('size' => 20)).
|
||||
$html->hidden('User/icode', array('value' => $icode));?>
|
||||
|
||||
</div>
|
||||
<div>
|
||||
<?php echo $html->submit('Login'); ?>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div style="clear: both;"></div>
|
||||
</div>
|
||||
<?php endif;
|
||||
if (isset($party) && isset($confirm_only)): ?>
|
||||
<p>You've been invited to attend <a href="<?php echo $html->url('/parties/view/'.$party['Party']['id']); ?>"><?php echo $party['Party']['name']; ?></a>.
|
||||
To join this party, <a href="<?php echo $html->url('/parties/invited/'.$icode.'/confirm');?>">click here</a>, or cancel this invitation by <a href="<?php echo $html->url('/parties/invited/cancel/');?>">clicking here</a>.</p>
|
||||
<?php endif; ?>
|
||||
@@ -1,11 +0,0 @@
|
||||
<?php if (isset($party)): ?>
|
||||
<strong><?php echo $party['Party']['name']?></strong><br/><?php echo $party['Party']['vname']; ?><br/><a href="<?php echo $html->url('/parties/view/'.$party['Party']['id'])?>">View Party</a>
|
||||
<?php else: ?>
|
||||
function addParties() {
|
||||
<?php foreach ($parties as $party):
|
||||
if (!empty($party['Party']['lat']) && !empty($party['Party']['long']) && !$party['Party']['canceled']): ?>
|
||||
addParty(<?php echo $party['Party']['lat'];?>, <?php echo $party['Party']['long']?>, <?php echo $party['Party']['id']; ?>);
|
||||
<?php endif; endforeach;?>
|
||||
}
|
||||
//
|
||||
<?php endif; ?>
|
||||
@@ -1,140 +0,0 @@
|
||||
<?php
|
||||
if (isset($party)): ?>
|
||||
<h1><?php echo $party['Party']['name']; ?></h1>
|
||||
<br/>
|
||||
<?php if ($party['Party']['canceled']): ?>
|
||||
<div class="error">This party has been canceled</div>
|
||||
<?php endif; ?>
|
||||
Host: <a href="<?php echo $html->url('/users/view/'.$party['Party']['owner']).'">'.$host; ?></a><br/>
|
||||
<?php
|
||||
if (!empty($party['Party']['address']))
|
||||
echo 'Location: '.$party['Party']['address']."<br/>\n";
|
||||
|
||||
if (!empty($party['Party']['vname']))
|
||||
echo 'Venue: '.$party['Party']['vname']."<br/>\n";
|
||||
|
||||
echo 'Date: '.(($party['Party']['confirmed'] == 1) ? gmdate('Y-m-d h:ia', $party['Party']['date'] + (@$_SESSION['User']['tz'] * 60 * 60))." GMT".@$_SESSION['User']['tz'] : "TBA")."<br/>\n";
|
||||
echo 'Duration: '.$party['Party']['duration'].' hour'.(($party['Party']['duration'] == 1) ? '' : 's')."\n<br/>";
|
||||
|
||||
if (!empty($party['Party']['website']) && preg_match("/^(http|https)\:\/\//i", $party['Party']['website']))
|
||||
echo 'Website: <a href="'.$party['Party']['website'].'" rel="nofollow">'.$party['Party']['website']."</a><br/>\n";
|
||||
|
||||
if (!empty($party['Party']['notes']))
|
||||
echo 'Notes: '.$party['Party']['notes']."<br/>\n";
|
||||
?>
|
||||
<br/>
|
||||
<script src="http://maps.google.com/maps?file=api&v=2&key=<?php echo GMAP_API_KEY; ?>"
|
||||
type="text/javascript"></script>
|
||||
<script src="<?php echo $html->url('/js/maps.js'); ?>" type="text/javascript"></script>
|
||||
<div id="map" class="small-map"></div>
|
||||
<h1>Who's coming</h1>
|
||||
<div>
|
||||
<?php if (!empty($guests)):
|
||||
$i = 0;
|
||||
$c = count($guests) - 1;
|
||||
foreach ($guests as $guest): ?>
|
||||
<a href="<?php echo $html->url('/users/view/'.$guest['users']['id']); ?>"><?php echo $guest['users']['name']; ?></a><?php echo ($i < $c) ? ", " : ""; ?>
|
||||
<?php $i++;
|
||||
endforeach;
|
||||
else:
|
||||
echo "No guests yet, be the first!";
|
||||
endif;
|
||||
|
||||
if (isset($_SESSION['User']['id']) && @$_SESSION['User']['id'] != $party['Party']['owner'] && ($party['Party']['inviteonly'] != 1 || $isguest && !$party['Party']['canceled'])):?>
|
||||
<br/><br/>
|
||||
<form action="<?php
|
||||
echo $html->url('/parties/'.((!$isguest) ? 'rsvp/' : 'unrsvp/').$party['Party']['id']); ?>" method="post">
|
||||
<?php if(!$isguest): ?>
|
||||
<button>Count me in!</button>
|
||||
<?php else: ?>
|
||||
<button>Remove me</button>
|
||||
<?php endif; ?>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
<? if ($party['Party']['inviteonly'] == 1 && (!$isguest && @$_SESSION['User']['id'] != $party['Party']['owner'] && !$party['Party']['canceled'])):?>
|
||||
<p>This party is invite only. You'll need an invite code from the host to join in.</p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php if (@$_SESSION['User']['id'] == $party['Party']['owner']):?>
|
||||
<h1>Party options</h1>
|
||||
<a href="<?php echo $html->url('/parties/edit/'.$party['Party']['id']);?>">Edit party</a>
|
||||
<?php if (!$party['Party']['canceled']): ?>| <a href="<?php echo $html->url('/parties/invite/'.$party['Party']['id']);?>">Invite a guest</a>
|
||||
<?php endif; echo (($party['Party']['canceled'] == 1) ? ' | <a href="'.$html->url('/parties/uncancel/'.$party['Party']['id']).'">
|
||||
Reactivate this party</a>' : '| <a href="'.$html->url('/parties/cancel/'.$party['Party']['id']).'" onclick="return confirm(\'Are you sure you want to cancel your party?\')"><span style="color: #bc1313">Cancel this party</span></a>'); ?>
|
||||
<?php endif; ?>
|
||||
<?php if (isset($flickr)): ?>
|
||||
<h1 id="photos">Photos <a title="Photo Feed" href="<?php echo $html->url('/feeds/photos/'.$party['Party']['id']); ?>"><img src="<?php echo $html->url('/img/feed16.png'); ?>" alt="Atom"/></a></h1>
|
||||
<div style="text-align: center">
|
||||
<?php if (empty($flickr)): ?>
|
||||
<p>No photos yet. Tag your flickr pictures with <?php echo FLICKR_TAG_PREFIX.$party['Party']['id']; ?> to display them here.</p>
|
||||
<?php else:
|
||||
foreach ($flickr as $pic): ?>
|
||||
<a href="http://www.flickr.com/photos/<?php echo $pic['owner']."/".$pic['id']."/" ?>"><img src="http://static.flickr.com/<?php echo $pic['server']."/".$pic['id']."_".$pic['secret']."_s.jpg" ?>" title="<?php echo $pic['title']; ?>"/></a>
|
||||
<?php endforeach;
|
||||
endif; ?>
|
||||
<br/>
|
||||
</div>
|
||||
<?php endif;
|
||||
if (!empty($comments)): ?>
|
||||
<h1 id="comments">Comments <a title="Comment Feed" href="<?php echo $html->url('/feeds/comments/'.$party['Party']['id']); ?>"><img src="<?php echo $html->url('/img/feed16.png'); ?>" alt="RSS"/></a></h1>
|
||||
<?php $i = 0;
|
||||
foreach ($comments as $comment):
|
||||
if ($i % 2 == 0)
|
||||
$class = "";
|
||||
else
|
||||
$class = "comment-mod";
|
||||
$i++;?>
|
||||
<div id="c<?php echo $comment['comments']['cid'];?>" class="comment <?php echo $class;?>">
|
||||
<span class="comment-content"><?php echo $comment['comments']['text']; ?></span>
|
||||
<span class="comment-tag"><br/><br/>Posted by <a href="<?php echo $html->url('/users/view/'.$comment['users']['uid']); ?>">
|
||||
<?php echo $comment['users']['name']; ?></a> on <?php echo gmdate('Y-m-d h:ia', $comment['comments']['time'] + (@$_SESSION['User']['tz'] * 60 * 60)); ?></span>
|
||||
</span>
|
||||
</div>
|
||||
<?php endforeach;
|
||||
endif;
|
||||
if (isset($_SESSION['User'])):
|
||||
if (($party['Party']['guestcomments'] && $isguest) || !$party['Party']['guestcomments'] || @$_SESSION['User']['id'] == $party['Party']['owner']): ?>
|
||||
<h1>Add a comment</h1>
|
||||
<form action="<?php echo $html->url('/comments/add/'.$party['Party']['id'].'/'.$_SESSION['User']['id']); ?>" method="post">
|
||||
<div>
|
||||
<?php echo $html->textarea('Comment/text', array('rows' => 10, 'cols' => 50))."<br/>".$html->submit('Submit'); ?>
|
||||
</div>
|
||||
</form>
|
||||
<?php endif;
|
||||
endif;
|
||||
endif; ?>
|
||||
|
||||
<?php if (isset($parties)):
|
||||
if (isset($prev))
|
||||
echo '<a href="'.$html->url('/parties/view/all/'.$prev).'">« Previous Page</a> ';
|
||||
if (isset($prev) && isset($next))
|
||||
echo ' | ';
|
||||
if (isset($next))
|
||||
echo '<a href="'.$html->url('/parties/view/all/'.$next).'">Next Page »</a>';
|
||||
$i = 0;
|
||||
foreach ($parties as $party):
|
||||
if ($party['Party']['canceled'] != 1): ?>
|
||||
<div>
|
||||
<h1><?php echo $party['Party']['name']; ?></h1>
|
||||
<p>
|
||||
<?php
|
||||
if (!empty($party['Party']['address']))
|
||||
echo 'Location: '.$party['Party']['address']."<br/>\n";
|
||||
|
||||
if (!empty($party['Party']['vname']))
|
||||
echo 'Venue: '.$party['Party']['vname']."<br/>\n";
|
||||
|
||||
echo 'Date: '.(($party['Party']['confirmed'] == 1) ? gmdate('Y-m-d h:ia', $party['Party']['date'] + (@$_SESSION['User']['tz'] * 60 * 60))." GMT".@$_SESSION['User']['tz'] : "TBA")."<br/>\n";
|
||||
|
||||
echo '<a href="'.$html->url('/parties/view/'.$party['Party']['id']).'">View Party</a>';
|
||||
?>
|
||||
</p>
|
||||
</div>
|
||||
<?php endif; endforeach;
|
||||
if (isset($prev))
|
||||
echo '<a href="'.$html->url('/parties/view/all/'.$prev).'">« Previous Page</a> ';
|
||||
if (isset($prev) && isset($next))
|
||||
echo ' | ';
|
||||
if (isset($next))
|
||||
echo '<a href="'.$html->url('/parties/view/all/'.$next).'">Next Page »</a>';
|
||||
endif;?>
|
||||
@@ -1,105 +0,0 @@
|
||||
<?php if ($error): ?>
|
||||
<div class="error">
|
||||
There was an error in your submission, please try again.
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<form class="fxform" action="<?php echo $html->url('/users/edit'); ?>" method="post">
|
||||
<?php echo $html->hidden('User/id'); ?>
|
||||
<h1>Profile</h1>
|
||||
<div>
|
||||
<label for="UserName" class="label-large">Name:</label>
|
||||
<?php echo $html->input('User/name', array('size' => 40)); ?>
|
||||
<?php echo $html->tagErrorMsg('User/name', 'You must enter a name.')?>
|
||||
</div>
|
||||
<div>
|
||||
<label for="UserWebsite" class="label-large">Website:</label>
|
||||
<?php echo $html->input('User/website', array('size' => 40)); ?>
|
||||
<?php echo $html->tagErrorMsg('User/website', 'Invalid URL.')?>
|
||||
</div>
|
||||
<div>
|
||||
<label for="location" class="label-large">Location:</label>
|
||||
<?php echo $html->input('User/location', array('id' => 'location', 'size' => 40, 'onkeypress' => 'capture(event)')); ?>
|
||||
</div>
|
||||
<div>
|
||||
<label for="UserTz" class="label-large">Timezone:</label>
|
||||
<?php
|
||||
$tzs = array('-12' => 'GMT-12',
|
||||
'-11' => 'GMT-11',
|
||||
'-10' => 'GMT-10',
|
||||
'-9' => 'GMT-9',
|
||||
'-8' => 'GMT-8',
|
||||
'-7' => 'GMT-7',
|
||||
'-6' => 'GMT-6',
|
||||
'-5' => 'GMT-5',
|
||||
'-4' => 'GMT-4',
|
||||
'-3' => 'GMT-3',
|
||||
'-2' => 'GMT-2',
|
||||
'-1' => 'GMT-1',
|
||||
'0' => 'GMT+0',
|
||||
'1' => 'GMT+1',
|
||||
'2' => 'GMT+2',
|
||||
'3' => 'GMT+3',
|
||||
'4' => 'GMT+4',
|
||||
'5' => 'GMT+5',
|
||||
'6' => 'GMT+6',
|
||||
'7' => 'GMT+7',
|
||||
'8' => 'GMT+8',
|
||||
'9' => 'GMT+9',
|
||||
'10' => 'GMT+10',
|
||||
'11' => 'GMT+11',
|
||||
'12' => 'GMT+12',
|
||||
'13' => 'GMT+13');
|
||||
echo $html->selectTag('User/tz', $tzs, $utz, null, null, false);
|
||||
?>
|
||||
(current time is <?php echo gmdate("Y-m-d H:i:s"); ?> GMT)
|
||||
</div>
|
||||
<?php if(GMAP_API_KEY != null): ?>
|
||||
<script src="http://maps.google.com/maps?file=api&v=2&key=<?php echo GMAP_API_KEY; ?>"
|
||||
type="text/javascript"></script>
|
||||
<script src="<?php echo $html->url('/js/maps.js'); ?>" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
|
||||
//<![CDATA[
|
||||
function update() {
|
||||
var loc = document.getElementById("location").value;
|
||||
geocode(loc);
|
||||
}
|
||||
|
||||
function capture(event) {
|
||||
if (event.keyCode == 13) {
|
||||
event.preventDefault();
|
||||
update();
|
||||
}
|
||||
}
|
||||
//]]>
|
||||
</script>
|
||||
<p id="map" class="small-map"></p>
|
||||
<?php echo $html->hidden('User/lat', array('id' => 'lat'));
|
||||
echo $html->hidden('User/long', array('id' => 'long'));
|
||||
echo $html->hidden('User/zoom', array('id' => 'zoom')); ?>
|
||||
<?php endif; ?>
|
||||
<h1>Privacy</h1>
|
||||
<div>
|
||||
<label for="UserShowemail" class="label-large">Show email:</label>
|
||||
<?php echo $html->checkbox('User/showemail'); ?><br/>
|
||||
</div>
|
||||
<div>
|
||||
<label for="UserShowloc" class="label-large">Show location:</label>
|
||||
<?php echo $html->checkbox('User/showloc'); ?><br/>
|
||||
</div>
|
||||
<div>
|
||||
<label for="UserShowmap" class="label-large">Show map:</label>
|
||||
<?php echo $html->checkbox('User/showmap'); ?><br/>
|
||||
</div>
|
||||
<h1>Password</h1>
|
||||
<div>
|
||||
<label for="UserPassword" class="label-large">New password:</label>
|
||||
<?php echo $html->password('User/password', array('size' => 20, 'autocomplete' => 'off')); ?>
|
||||
</div>
|
||||
<div>
|
||||
<label for="UserConfpassword" class="label-large">Confirm new password:</label>
|
||||
<?php echo $html->password('User/confpassword', array('size' => 20, 'autocomplete' => 'off')); ?>
|
||||
<?php echo $html->tagErrorMsg('User/confpassword', 'The supplied passwords do not match!')?>
|
||||
</div>
|
||||
<?php echo $html->submit('Update'); ?>
|
||||
</form>
|
||||
@@ -1,61 +0,0 @@
|
||||
<h1>My Profile</h1>
|
||||
<br/>
|
||||
<h2>Parties I'm attending</h2>
|
||||
<p>
|
||||
<?php
|
||||
$num_parties = count($parties);
|
||||
if ($num_parties == 0)
|
||||
echo 'None yet. <a href="'.$html->url('/parties/view/all').'">Find one!</a>';
|
||||
|
||||
else {
|
||||
$c = $num_parties - 1;
|
||||
$i = 0;
|
||||
foreach ($parties as $party) {
|
||||
echo '<a href="'.$html->url('/parties/view/'.$party['parties']['id']).'">'.$party['parties']['name'].'</a>';
|
||||
echo ($i < $c) ? ', ' : '';
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
?>
|
||||
</p>
|
||||
<h2>Parties I'm hosting</h2>
|
||||
<p>
|
||||
<?php
|
||||
$num_parties = count($hparties);
|
||||
if (empty($hparties))
|
||||
echo 'None yet. <a href="'.$html->url('/parties/add').'">Create one!</a>';
|
||||
|
||||
else {
|
||||
$c = $num_parties - 1;
|
||||
$i = 0;
|
||||
foreach ($hparties as $party) {
|
||||
echo '<a href="'.$html->url('/parties/view/'.$party['parties']['id']).'">'.$party['parties']['name'].'</a>';
|
||||
echo ($i < $c) ? ', ' : '';
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
?>
|
||||
<h2>Parties I've been invited to</h2>
|
||||
<p>
|
||||
<?php
|
||||
$num_parties = count($iparties);
|
||||
if (empty($iparties))
|
||||
echo 'None yet.';
|
||||
|
||||
else {
|
||||
$c = $num_parties - 1;
|
||||
$i = 0;
|
||||
foreach ($iparties as $party) {
|
||||
echo '<a href="'.$html->url('/parties/view/'.$party['parties']['id']).'">'.$party['parties']['name'].'</a>';
|
||||
echo ($i < $c) ? ', ' : '';
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
?>
|
||||
</p>
|
||||
<h2>Account Options</h2>
|
||||
<p>
|
||||
<a href="<?php echo $html->url('/users/edit'); ?>">Edit my account</a>
|
||||
<br/>
|
||||
<a href="<?php echo $html->url('/users/logout'); ?>">Logout</a>
|
||||
</p>
|
||||
@@ -1,17 +0,0 @@
|
||||
<h1>Login</h1>
|
||||
<form class="fxform" action="<?php echo $html->url('/users/login'); ?>" method="post">
|
||||
<div>
|
||||
<label class="label-large" for="UserEmail">Email Address:</label>
|
||||
<?php echo $html->input('User/email', array('size' => 40)); ?>
|
||||
</div>
|
||||
<div>
|
||||
<label class="label-large" for="UserPassword">Password:</label>
|
||||
<?php echo $html->password('User/password', array('size' => 40)); ?>
|
||||
</div>
|
||||
<div>
|
||||
<?php echo $html->submit('Login'); ?>
|
||||
</div>
|
||||
<p>
|
||||
<a href="<?php echo $html->url('/users/register'); ?>">Create an account</a> | <a href="<?php echo $html->url('/users/recover/password'); ?>">Forgot your password?</a>
|
||||
</p>
|
||||
</form>
|
||||
@@ -1,26 +0,0 @@
|
||||
<h1><?php echo $atitle; ?></h1>
|
||||
<form class="fxform" action="<?php
|
||||
if (isset($reset))
|
||||
echo $html->url('/users/recover/reset/'.$code);
|
||||
else
|
||||
echo $html->url('/users/recover/'.$url); ?>" method="post">
|
||||
<?php if (isset($error)): ?>
|
||||
<div class="error">
|
||||
<?php echo $error; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<div>
|
||||
<?php if (!$hideInput): ?>
|
||||
<label class="label-large" for="UserEmail">Email address:</label>
|
||||
<?php echo $html->input('User/email'); ?>
|
||||
<?php endif;
|
||||
if (isset($reset)): ?>
|
||||
<label class="label-large" for="UserPassword">New password:</label>
|
||||
<?php echo $html->password('User/password'); ?>
|
||||
<br/>
|
||||
<label class="label-large" for="UserConfirm">Confirm password:</label>
|
||||
<?php echo $html->password('User/confirm'); ?>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php echo $html->submit('Submit'); ?>
|
||||
</form>
|
||||
@@ -1,110 +0,0 @@
|
||||
<h1>Register</h1>
|
||||
<form class="fxform" action="<?php echo $html->url('/users/register'); ?>" method="post">
|
||||
<p>Your e-mail address is used as your username to login. You'll also receive a confirmation e-mail to
|
||||
this address. In order for your account to be activated successfully, you must specify a valid e-mail address.</p>
|
||||
<div>
|
||||
<label class="label-large" for="UserEmail">Email address<span class="required">*</span>:</label>
|
||||
<?php echo $html->input('User/email', array('size' => 40)); ?>
|
||||
<?php echo $html->tagErrorMsg('User/email', 'The email address you entered is invalid or has already been registered.')?>
|
||||
</div>
|
||||
<div>
|
||||
<label class="label-large" for="UserConfemail">Confirm Email address<span class="required">*</span>:</label>
|
||||
<?php echo $html->input('User/confemail', array('size' => 40)); ?>
|
||||
<?php echo $html->tagErrorMsg('User/confemail', 'The email addresses you entered do not match.')?>
|
||||
</div>
|
||||
<p>How do you want to be known to visitors of <?php echo APP_NAME; ?>?</p>
|
||||
<div>
|
||||
<label class="label-large" for="UserName">Name<span class="required">*</span>:</label>
|
||||
<?php echo $html->input('User/name', array('size' => 40)); ?>
|
||||
<?php echo $html->tagErrorMsg('User/name', 'You must enter a name.')?>
|
||||
</div>
|
||||
<p>If you choose to enter it, your location will be shown on your profile. This
|
||||
field is optional.
|
||||
<div>
|
||||
<label class="label-large" for="UserLocation">Location:</label>
|
||||
<?php echo $html->input('User/location', array('id' => 'location', 'size' => 40, 'onkeypress' => 'capture(event)', 'onblur' => 'update()')); ?>
|
||||
<div id="locerr" class="info" style="display: none">Did you mean: <a id="locerrlink" onclick="geocode_suggest()" href="#"></a>? <a href="#" onclick="shide()"><span style="font-size: x-small">(close)</span></a></div>
|
||||
</div>
|
||||
<p>If you have a website, enter the URL here. (including the http:// ) Your website will be
|
||||
shown to site visitors on your author profile page. This field is optional; if you don't
|
||||
have a website or don't want it linked to from <?php echo APP_NAME; ?>, leave this box blank.</p>
|
||||
<div>
|
||||
<label class="label-large" for="UserWebsite">Website:</label>
|
||||
<?php echo $html->input('User/website', array('size' => 40)); ?>
|
||||
<?php echo $html->tagErrorMsg('User/website', 'Invalid URL.')?>
|
||||
</div>
|
||||
<div>
|
||||
<label class="label-large" for="UserTz">Timezone<span class="required">*</span>:</label>
|
||||
<?php
|
||||
$tzs = array('-12' => 'GMT-12',
|
||||
'-11' => 'GMT-11',
|
||||
'-10' => 'GMT-10',
|
||||
'-9' => 'GMT-9',
|
||||
'-8' => 'GMT-8',
|
||||
'-7' => 'GMT-7',
|
||||
'-6' => 'GMT-6',
|
||||
'-5' => 'GMT-5',
|
||||
'-4' => 'GMT-4',
|
||||
'-3' => 'GMT-3',
|
||||
'-2' => 'GMT-2',
|
||||
'-1' => 'GMT-1',
|
||||
'0' => 'GMT+0',
|
||||
'1' => 'GMT+1',
|
||||
'2' => 'GMT+2',
|
||||
'3' => 'GMT+3',
|
||||
'4' => 'GMT+4',
|
||||
'5' => 'GMT+5',
|
||||
'6' => 'GMT+6',
|
||||
'7' => 'GMT+7',
|
||||
'8' => 'GMT+8',
|
||||
'9' => 'GMT+9',
|
||||
'10' => 'GMT+10',
|
||||
'11' => 'GMT+11',
|
||||
'12' => 'GMT+12',
|
||||
'13' => 'GMT+13');
|
||||
echo $html->selectTag('User/tz', $tzs, $utz, null, null, false);
|
||||
?>
|
||||
(this page was loaded at <?php echo gmdate("Y-m-d H:i:s"); ?> GMT)
|
||||
</div>
|
||||
<div>
|
||||
<label class="label-large" for="password">Password<span class="required">*</span>:</label>
|
||||
<?php echo $html->password('User/password', array('size' => 40)); ?>
|
||||
<?php echo $html->tagErrorMsg('User/password', 'You must enter a password.')?>
|
||||
</div>
|
||||
<div>
|
||||
<label class="label-large" for="confpassword">Confirm password<span class="required">*</span>:</label>
|
||||
<?php echo $html->password('User/confpass', array('size' => 40)); ?>
|
||||
<?php echo $html->tagErrorMsg('User/confpass', 'The passwords you supplied do not match.')?>
|
||||
</div>
|
||||
<?php if(GMAP_API_KEY != null): ?>
|
||||
<script src="http://maps.google.com/maps?file=api&v=2&key=<?php echo GMAP_API_KEY; ?>"
|
||||
type="text/javascript"></script>
|
||||
<script src="<?php echo $html->url('/js/maps.js'); ?>" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
function update() {
|
||||
var loc = document.getElementById("location").value;
|
||||
geocode(loc);
|
||||
}
|
||||
|
||||
function capture(event) {
|
||||
if (event.keyCode == 13) {
|
||||
event.preventDefault();
|
||||
update();
|
||||
}
|
||||
}
|
||||
//]]>
|
||||
</script>
|
||||
<p><span class="required">*</span> Required field</p>
|
||||
<p>Drag the map or the marker to specify your location. Set the zoom by using the '+' or '-' buttons on the left.</p>
|
||||
<p id="map" class="med-map-r"></p>
|
||||
<div>
|
||||
<?php echo $html->hidden('User/lat', array('id' => 'lat'));
|
||||
echo $html->hidden('User/long', array('id' => 'long'));
|
||||
echo $html->hidden('User/zoom', array('id' => 'zoom'));
|
||||
echo $html->hidden('User/geocoded', array('id' => 'geocoded', 'value' => 0));
|
||||
echo $html->hidden('User/icode', array('value' => @$icode)); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php echo $html->submit('Register'); ?>
|
||||
</form>
|
||||
@@ -1,44 +0,0 @@
|
||||
<?php
|
||||
if (!empty($user['User']['name']))
|
||||
echo "<h1>".$user['User']['name']."</h1><br/>";
|
||||
|
||||
if ($user['User']['showemail'] == 1 && @$_SESSION['User'])
|
||||
echo "Email: ".$user['User']['email']."<br/>";
|
||||
|
||||
if ($user['User']['showloc'] == 1 && !empty($user['User']['location']))
|
||||
echo "Location: ".$user['User']['location']."<br/>";
|
||||
|
||||
if (!empty($user['User']['website']) && preg_match("/^(http|https)\:\/\//i", $user['User']['website']))
|
||||
echo 'Website: <a href="'.$user['User']['website'].'" rel="nofollow">'.$user['User']['website'].'</a><br/>';
|
||||
|
||||
if (!empty($parties)) {
|
||||
echo "Attending: ";
|
||||
$c = count($parties) - 1;
|
||||
$i = 0;
|
||||
|
||||
foreach ($parties as $party) {
|
||||
echo '<a href="'.$html->url('/parties/view/'.$party['parties']['id']).'">'.$party['parties']['name'].'</a>';
|
||||
echo ($i < $c) ? ', ' : '<br/>';
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($hparties)) {
|
||||
echo "Hosting: ";
|
||||
$c = count($hparties) - 1;
|
||||
$i = 0;
|
||||
|
||||
foreach ($hparties as $party) {
|
||||
echo '<a href="'.$html->url('/parties/view/'.$party['parties']['id']).'">'.$party['parties']['name'].'</a>';
|
||||
echo ($i < $c) ? ', ' : '<br/>';
|
||||
$i++;
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
<?php if(isset($map) && $user['User']['showmap'] == 1): ?>
|
||||
<br/>
|
||||
<script src="http://maps.google.com/maps?file=api&v=2&key=<?php echo GMAP_API_KEY; ?>" type="text/javascript"></script>
|
||||
<script src="<?php echo $html->url('/js/maps.js'); ?>" type="text/javascript"></script>
|
||||
<div id="map" style="height: 200px; width: 350px;"></div>
|
||||
<?php endif; ?>
|
||||
@@ -1,6 +0,0 @@
|
||||
<IfModule mod_rewrite.c>
|
||||
RewriteEngine On
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
|
||||
</IfModule>
|
||||
@@ -1,101 +0,0 @@
|
||||
<?php
|
||||
/* SVN FILE: $Id: css.php,v 1.4 2006-10-08 03:39:23 reed%reedloden.com Exp $ */
|
||||
/**
|
||||
* Short description for file.
|
||||
*
|
||||
* Long description for file
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
*
|
||||
* CakePHP : Rapid Development Framework <http://www.cakephp.org/>
|
||||
* Copyright (c) 2006, Cake Software Foundation, Inc.
|
||||
* 1785 E. Sahara Avenue, Suite 490-204
|
||||
* Las Vegas, Nevada 89104
|
||||
*
|
||||
* Licensed under The MIT License
|
||||
* Redistributions of files must retain the above copyright notice.
|
||||
*
|
||||
* @filesource
|
||||
* @copyright Copyright (c) 2006, Cake Software Foundation, Inc.
|
||||
* @link http://www.cakefoundation.org/projects/info/cakephp CakePHP Project
|
||||
* @package cake
|
||||
* @subpackage cake.app.webroot
|
||||
* @since CakePHP v 0.2.9
|
||||
* @version $Revision: 1.4 $
|
||||
* @modifiedby $LastChangedBy: phpnut $
|
||||
* @lastmodified $Date: 2006-10-08 03:39:23 $
|
||||
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
|
||||
*/
|
||||
if (!defined('CAKE_CORE_INCLUDE_PATH')) {
|
||||
header('HTTP/1.1 404 Not Found');
|
||||
}
|
||||
/**
|
||||
* Enter description here...
|
||||
*/
|
||||
require(LIBS . 'folder.php');
|
||||
require(LIBS . 'legacy.php');
|
||||
/**
|
||||
* Enter description here...
|
||||
*
|
||||
* @param unknown_type $path
|
||||
* @param unknown_type $name
|
||||
* @return unknown
|
||||
*/
|
||||
function make_clean_css($path, $name) {
|
||||
require(VENDORS . 'csspp' . DS . 'csspp.php');
|
||||
$data =file_get_contents($path);
|
||||
$csspp =new csspp();
|
||||
$output=$csspp->compress($data);
|
||||
$ratio =100 - (round(strlen($output) / strlen($data), 3) * 100);
|
||||
$output=" /* file: $name, ratio: $ratio% */ " . $output;
|
||||
return $output;
|
||||
}
|
||||
/**
|
||||
* Enter description here...
|
||||
*
|
||||
* @param unknown_type $path
|
||||
* @param unknown_type $content
|
||||
* @return unknown
|
||||
*/
|
||||
function write_css_cache($path, $content) {
|
||||
if (!is_dir(dirname($path))) {
|
||||
mkdir(dirname($path));
|
||||
}
|
||||
$cache=new File($path);
|
||||
return $cache->write($content);
|
||||
}
|
||||
|
||||
if (preg_match('|\.\.|', $url) || !preg_match('|^ccss/(.+)$|i', $url, $regs)) {
|
||||
die('Wrong file name.');
|
||||
}
|
||||
|
||||
$filename = 'css/' . $regs[1];
|
||||
$filepath = CSS . $regs[1];
|
||||
$cachepath = CACHE . 'css' . DS . str_replace(array('/','\\'), '-', $regs[1]);
|
||||
|
||||
if (!file_exists($filepath)) {
|
||||
die('Wrong file name.');
|
||||
}
|
||||
|
||||
if (file_exists($cachepath)) {
|
||||
$templateModified=filemtime($filepath);
|
||||
$cacheModified =filemtime($cachepath);
|
||||
|
||||
if ($templateModified > $cacheModified) {
|
||||
$output=make_clean_css($filepath, $filename);
|
||||
write_css_cache($cachepath, $output);
|
||||
} else {
|
||||
$output = file_get_contents($cachepath);
|
||||
}
|
||||
} else {
|
||||
$output=make_clean_css($filepath, $filename);
|
||||
write_css_cache($cachepath, $output);
|
||||
}
|
||||
|
||||
header("Date: " . date("D, j M Y G:i:s ", $templateModified) . 'GMT');
|
||||
header("Content-Type: text/css");
|
||||
header("Expires: " . gmdate("D, j M Y H:i:s", time() + DAY) . " GMT");
|
||||
header("Cache-Control: cache"); // HTTP/1.1
|
||||
header("Pragma: cache"); // HTTP/1.0
|
||||
print $output;
|
||||
?>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user