Add command line options for optimization

This commit is contained in:
drmortalwombat 2021-10-14 16:51:59 +02:00
parent fc0f8e2442
commit e2e6f4ea01
18 changed files with 183 additions and 159 deletions

View File

@ -73,6 +73,11 @@ The compiler is command line driven, and creates an executable .prg file.
* -e : execute the result in the integrated emulator
* -n : create pure native code for all functions
* -d : define a symbol (e.g. NOFLOAT or NOLONG to avoid float/long code in printf)
* -O1 or -O : default optimizations
* -O0: disable optimizations
* -O2: more aggressive speed optimizations including auto inline of small functions
* -O3: aggressive optimization for speed
* -Os: optimize for size
A list of source files can be provided.

View File

@ -1,195 +1,142 @@
@echo off
..\release\oscar64 -e stdlibtest.c
call :test stdlibtest.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -n stdlibtest.c
call :test testint16.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e testint16.c
call :test testint32.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -n testint16.c
call :test testint16mul.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e testint32.c
call :test recursiontest.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -n testint32.c
call :test strcmptest.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e testint16mul.c
call :test strcmptest2.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -n testint16mul.c
call :test arraytest.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e recursiontest.c
call :test arraytestfloat.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -n recursiontest.c
call :test optiontest.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e strcmptest.c
call :test floatcmptest.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -n strcmptest.c
call :test floatmultest.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e strcmptest2.c
call :test staticconsttest.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -n strcmptest2.c
call :test arrayinittest.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e arraytest.c
call :test array2stringinittest.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -n arraytest.c
call :test testint16cmp.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e arraytestfloat.c
call :test testint32cmp.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -n arraytestfloat.c
call :test floatstringtest.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e optiontest.c
call :test qsorttest.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -n optiontest.c
call :test loopdomtest.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e floatcmptest.c
call :test byteindextest.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -n floatcmptest.c
call :test asmtest.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e floatmultest.c
call :testb bitshifttest.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -n floatmultest.c
call :test arrparam.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e staticconsttest.c
call :test bsstest.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -n staticconsttest.c
call :test copyintvec.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e arrayinittest.c
call :test divmodtest.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -n arrayinittest.c
call :test enumswitch.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e array2stringinittest.c
call :test incvector.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -n array2stringinittest.c
call :test structoffsettest2.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e testint16cmp.c
call :test funcvartest.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -n testint16cmp.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e testint32cmp.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -n testint32cmp.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e floatstringtest.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -n floatstringtest.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e qsorttest.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -n qsorttest.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e loopdomtest.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -n loopdomtest.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e byteindextest.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -n byteindextest.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e asmtest.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -n asmtest.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e bitshifttest.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -n bitshifttest.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e arrparam.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -n arrparam.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e bsstest.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -n bsstest.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e copyintvec.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -n copyintvec.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e divmodtest.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -n divmodtest.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e enumswitch.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -n enumswitch.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e incvector.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -n incvector.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e structoffsettest2.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -n structoffsettest2.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e funcvartest.c
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -n funcvartest.c
if %errorlevel% neq 0 goto :error
exit /b 0
:error
echo Failed with error #%errorlevel%.
exit /b %errorlevel%
:test
..\release\oscar64 -e %~1
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -n %~1
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -O2 %~1
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -O2 -n %~1
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -O0 %~1
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -O0 -n %~1
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -O3 %~1
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -O3 -n %~1
if %errorlevel% neq 0 goto :error
exit /b 0
:testb
..\release\oscar64 -e %~1
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -O2 %~1
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -O0 %~1
if %errorlevel% neq 0 goto :error
..\release\oscar64 -e -O3 %~1
if %errorlevel% neq 0 goto :error
exit /b 0

View File

@ -9,7 +9,7 @@
#include <stdio.h>
Compiler::Compiler(void)
: mByteCodeFunctions(nullptr), mNativeCode(false), mDefines({nullptr, nullptr})
: mByteCodeFunctions(nullptr), mCompilerOptions(COPT_DEFAULT), mDefines({nullptr, nullptr})
{
mErrors = new Errors();
mLinker = new Linker(mErrors);
@ -36,11 +36,6 @@ Compiler::~Compiler(void)
}
void Compiler::ForceNativeCode(bool native)
{
mNativeCode = native;
}
void Compiler::AddDefine(const Ident* ident, const char* value)
{
Define define;
@ -157,12 +152,15 @@ bool Compiler::GenerateCode(void)
dcrtstart->mSection = sectionStartup;
mGlobalAnalyzer->mCompilerOptions = mCompilerOptions;
mGlobalAnalyzer->AnalyzeAssembler(dcrtstart->mValue, nullptr);
mGlobalAnalyzer->DumpCallGraph();
mGlobalAnalyzer->AutoInline();
mGlobalAnalyzer->DumpCallGraph();
mInterCodeGenerator->mForceNativeCode = mNativeCode;
mInterCodeGenerator->mCompilerOptions = mCompilerOptions;
mInterCodeGenerator->TranslateAssembler(mInterCodeModule, dcrtstart->mValue, nullptr);
if (mErrors->mErrorCount != 0)

View File

@ -8,6 +8,7 @@
#include "InterCodeGenerator.h"
#include "GlobalAnalyzer.h"
#include "Linker.h"
#include "CompilerTypes.h"
class Compiler
{
@ -27,7 +28,7 @@ public:
GrowingArray<ByteCodeProcedure*> mByteCodeFunctions;
bool mNativeCode;
uint64 mCompilerOptions;
struct Define
{
@ -42,7 +43,6 @@ public:
bool WriteOutputFile(const char* targetPath);
int ExecuteCode(void);
void ForceNativeCode(bool native);
void AddDefine(const Ident* ident, const char* value);
void RegisterRuntime(const Location& loc, const Ident* ident);

23
oscar64/CompilerTypes.h Normal file
View File

@ -0,0 +1,23 @@
#pragma once
#include "MachineTypes.h"
static const uint64 COPT_OPTIMIZE_BASIC = 0x00000001;
static const uint64 COPT_OPTIMIZE_INLINE = 0x00000002;
static const uint64 COPT_OPTIMIZE_AUTO_INLINE = 0x00000010;
static const uint64 COPT_OPTIMIZE_AUTO_INLINE_ALL = 0x00000020;
static const uint64 COPT_NATIVE = 0x01000000;
static const uint64 COPT_DEFAULT = COPT_OPTIMIZE_BASIC | COPT_OPTIMIZE_INLINE;
static const uint64 COPT_OPTIMIZE_DEFAULT = COPT_OPTIMIZE_BASIC | COPT_OPTIMIZE_INLINE;
static const uint64 COPT_OPTIMIZE_SIZE = COPT_OPTIMIZE_BASIC | COPT_OPTIMIZE_INLINE;
static const uint64 COPT_OPTIMIZE_SPEED = COPT_OPTIMIZE_BASIC | COPT_OPTIMIZE_INLINE | COPT_OPTIMIZE_AUTO_INLINE;
static const uint64 COPT_OPTIMIZE_ALL = COPT_OPTIMIZE_BASIC | COPT_OPTIMIZE_INLINE | COPT_OPTIMIZE_AUTO_INLINE | COPT_OPTIMIZE_AUTO_INLINE_ALL;

View File

@ -337,7 +337,7 @@ Expression* Expression::ConstantFold(void)
}
Declaration::Declaration(const Location& loc, DecType type)
: mLocation(loc), mType(type), mScope(nullptr), mData(nullptr), mIdent(nullptr), mSize(0), mOffset(0), mFlags(0), mComplexity(0), mBase(nullptr), mParams(nullptr), mValue(nullptr), mNext(nullptr), mVarIndex(-1), mLinkerObject(nullptr), mCallers(nullptr), mCalled(nullptr)
: mLocation(loc), mType(type), mScope(nullptr), mData(nullptr), mIdent(nullptr), mSize(0), mOffset(0), mFlags(0), mComplexity(0), mLocalSize(0), mBase(nullptr), mParams(nullptr), mValue(nullptr), mNext(nullptr), mVarIndex(-1), mLinkerObject(nullptr), mCallers(nullptr), mCalled(nullptr)
{}
Declaration::~Declaration(void)

View File

@ -165,7 +165,7 @@ public:
Declaration* mBase, *mParams, * mNext;
Expression* mValue;
DeclarationScope* mScope;
int mOffset, mSize, mVarIndex, mNumVars, mComplexity;
int mOffset, mSize, mVarIndex, mNumVars, mComplexity, mLocalSize;
int64 mInteger;
double mNumber;
uint32 mFlags;

View File

@ -671,6 +671,9 @@ int Emulator::Emulate(int startIP)
if (mRegS == 0)
{
for (int i = 0; i < 256; i++)
if (mMemory[i] != 0)
printf("ZP %02x : %02x\n", i, mMemory[i]);
DumpCycles();
return int16(mMemory[BC_REG_ACCU] + 256 * mMemory[BC_REG_ACCU + 1]);
}

View File

@ -1,7 +1,7 @@
#include "GlobalAnalyzer.h"
GlobalAnalyzer::GlobalAnalyzer(Errors* errors, Linker* linker)
: mErrors(errors), mLinker(linker), mCalledFunctions(nullptr), mCallingFunctions(nullptr), mVariableFunctions(nullptr), mFunctions(nullptr)
: mErrors(errors), mLinker(linker), mCalledFunctions(nullptr), mCallingFunctions(nullptr), mVariableFunctions(nullptr), mFunctions(nullptr), mCompilerOptions(COPT_DEFAULT)
{
}
@ -59,7 +59,7 @@ void GlobalAnalyzer::AutoInline(void)
for (int i = 0; i < mFunctions.Size(); i++)
{
Declaration* f = mFunctions[i];
if (!(f->mFlags & DTF_INLINE) && !(f->mBase->mFlags & DTF_VARIADIC) && !(f->mFlags & DTF_FUNC_VARIABLE) && !(f->mFlags & DTF_FUNC_ASSEMBLER) && !(f->mFlags & DTF_INTRINSIC) && !(f->mFlags & DTF_FUNC_RECURSIVE))
if (!(f->mFlags & DTF_INLINE) && !(f->mBase->mFlags & DTF_VARIADIC) && !(f->mFlags & DTF_FUNC_VARIABLE) && !(f->mFlags & DTF_FUNC_ASSEMBLER) && !(f->mFlags & DTF_INTRINSIC) && !(f->mFlags & DTF_FUNC_RECURSIVE) && f->mLocalSize < 100)
{
int nparams = 0;
Declaration* dec = f->mParams;
@ -70,8 +70,16 @@ void GlobalAnalyzer::AutoInline(void)
}
int cost = (f->mComplexity - 20 * nparams);
if (cost * (f->mCallers.Size() - 1) <= 0 || (f->mFlags & DTF_REQUEST_INLINE))
//if (cost * (f->mCallers.Size() - 1) <= 1000 || (f->mFlags & DTF_REQUEST_INLINE))
bool doinline = false;
if ((mCompilerOptions & COPT_OPTIMIZE_INLINE) && (f->mFlags & DTF_INLINE))
doinline = true;
if ((mCompilerOptions & COPT_OPTIMIZE_AUTO_INLINE) && (cost * (f->mCallers.Size() - 1) <= 0))
doinline = true;
if ((mCompilerOptions & COPT_OPTIMIZE_AUTO_INLINE_ALL) && (cost * (f->mCallers.Size() - 1) <= 10000))
doinline = true;
if (doinline)
{
printf("INLINING %s %d * (%d - 1)\n", f->mIdent->mString, cost, f->mCallers.Size());
f->mFlags |= DTF_INLINE;
@ -245,6 +253,14 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec)
return exp->mDecValue;
case EX_VARIABLE:
if (!(exp->mDecValue->mFlags & DTF_STATIC) && !(exp->mDecValue->mFlags & DTF_GLOBAL))
{
if (!(exp->mDecValue->mFlags & DTF_ANALYZED))
{
procDec->mLocalSize += exp->mDecValue->mSize;
exp->mDecValue->mFlags |= DTF_ANALYZED;
}
}
return exp->mDecValue;
case EX_ASSIGNMENT:
ldec = Analyze(exp->mLeft, procDec);

View File

@ -2,6 +2,7 @@
#include "Declaration.h"
#include "Linker.h"
#include "CompilerTypes.h"
class GlobalAnalyzer
{
@ -16,6 +17,8 @@ public:
void AnalyzeAssembler(Expression* exp, Declaration* procDec);
void AnalyzeGlobalVariable(Declaration* dec);
uint64 mCompilerOptions;
protected:
Errors* mErrors;
Linker* mLinker;

View File

@ -86,7 +86,7 @@ void ValueSet::FlushCallAliases(void)
}
}
static int64 ConstantFolding(InterOperator oper, int64 val1, int64 val2 = 0)
static int64 ConstantFolding(InterOperator oper, InterType type, int64 val1, int64 val2 = 0)
{
switch (oper)
{
@ -133,7 +133,18 @@ static int64 ConstantFolding(InterOperator oper, int64 val1, int64 val2 = 0)
return (uint64)val1 >> (uint64)val2;
break;
case IA_SAR:
switch (type)
{
case IT_INT8:
return int8(val1) >> val2;
case IT_INT16:
return int16(val1) >> val2;
case IT_INT32:
return int32(val1) >> val2;
default:
return val1 >> val2;
}
break;
case IA_CMPEQ:
return val1 == val2 ? 1 : 0;
@ -679,7 +690,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr
ins->mSrc[0].mTemp >= 0 && tvalue[ins->mSrc[0].mTemp] && tvalue[ins->mSrc[0].mTemp]->mCode == IC_CONSTANT)
{
ins->mCode = IC_CONSTANT;
ins->mConst.mIntConst = ConstantFolding(ins->mOperator, tvalue[ins->mSrc[1].mTemp]->mConst.mIntConst, tvalue[ins->mSrc[0].mTemp]->mConst.mIntConst);
ins->mConst.mIntConst = ConstantFolding(ins->mOperator, ins->mDst.mType, tvalue[ins->mSrc[1].mTemp]->mConst.mIntConst, tvalue[ins->mSrc[0].mTemp]->mConst.mIntConst);
ins->mSrc[0].mTemp = -1;
ins->mSrc[1].mTemp = -1;
@ -926,7 +937,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr
if (ins->mSrc[0].mTemp >= 0 && tvalue[ins->mSrc[0].mTemp] && tvalue[ins->mSrc[0].mTemp]->mCode == IC_CONSTANT)
{
ins->mCode = IC_CONSTANT;
ins->mConst.mIntConst = ConstantFolding(ins->mOperator, tvalue[ins->mSrc[0].mTemp]->mConst.mIntConst);
ins->mConst.mIntConst = ConstantFolding(ins->mOperator, ins->mDst.mType, tvalue[ins->mSrc[0].mTemp]->mConst.mIntConst);
ins->mSrc[0].mTemp = -1;
i = 0;
@ -999,7 +1010,7 @@ void ValueSet::UpdateValue(InterInstruction * ins, const GrowingInstructionPtrAr
ins->mSrc[0].mTemp >= 0 && tvalue[ins->mSrc[0].mTemp] && tvalue[ins->mSrc[0].mTemp]->mCode == IC_CONSTANT)
{
ins->mCode = IC_CONSTANT;
ins->mConst.mIntConst = ConstantFolding(ins->mOperator, tvalue[ins->mSrc[1].mTemp]->mConst.mIntConst, tvalue[ins->mSrc[0].mTemp]->mConst.mIntConst);
ins->mConst.mIntConst = ConstantFolding(ins->mOperator, ins->mDst.mType, tvalue[ins->mSrc[1].mTemp]->mConst.mIntConst, tvalue[ins->mSrc[0].mTemp]->mConst.mIntConst);
ins->mSrc[0].mTemp = -1;
ins->mSrc[1].mTemp = -1;
@ -2138,7 +2149,7 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction * ins, const GrowingI
if (ins->mSrc[0].mTemp >= 0 && tvalue[ins->mSrc[0].mTemp] && tvalue[ins->mSrc[0].mTemp]->mCode == IC_CONSTANT)
{
ins->mCode = IC_CONSTANT;
ins->mConst.mIntConst = ConstantFolding(ins->mOperator, tvalue[ins->mSrc[1].mTemp]->mConst.mIntConst, tvalue[ins->mSrc[0].mTemp]->mConst.mIntConst);
ins->mConst.mIntConst = ConstantFolding(ins->mOperator, ins->mDst.mType, tvalue[ins->mSrc[1].mTemp]->mConst.mIntConst, tvalue[ins->mSrc[0].mTemp]->mConst.mIntConst);
ins->mSrc[0].mTemp = -1;
ins->mSrc[1].mTemp = -1;
}
@ -2234,12 +2245,12 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction * ins, const GrowingI
{
if (pins->mSrc[1].mTemp < 0)
{
ins->mSrc[1].mIntConst = ConstantFolding(ins->mOperator, ins->mSrc[1].mIntConst, pins->mSrc[1].mIntConst);
ins->mSrc[1].mIntConst = ConstantFolding(ins->mOperator, ins->mDst.mType, ins->mSrc[1].mIntConst, pins->mSrc[1].mIntConst);
ins->mSrc[0].mTemp = pins->mSrc[0].mTemp;
}
else if (pins->mSrc[0].mTemp < 0)
{
ins->mSrc[1].mIntConst = ConstantFolding(ins->mOperator, ins->mSrc[1].mIntConst, pins->mSrc[0].mIntConst);
ins->mSrc[1].mIntConst = ConstantFolding(ins->mOperator, ins->mDst.mType, ins->mSrc[1].mIntConst, pins->mSrc[0].mIntConst);
ins->mSrc[0].mTemp = pins->mSrc[1].mTemp;
}
}
@ -2251,12 +2262,12 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction * ins, const GrowingI
{
if (pins->mSrc[1].mTemp < 0)
{
ins->mSrc[0].mIntConst = ConstantFolding(ins->mOperator, ins->mSrc[0].mIntConst, pins->mSrc[1].mIntConst);
ins->mSrc[0].mIntConst = ConstantFolding(ins->mOperator, ins->mDst.mType, ins->mSrc[0].mIntConst, pins->mSrc[1].mIntConst);
ins->mSrc[1].mTemp = pins->mSrc[0].mTemp;
}
else if (pins->mSrc[0].mTemp < 0)
{
ins->mSrc[0].mIntConst = ConstantFolding(ins->mOperator, ins->mSrc[0].mIntConst, pins->mSrc[0].mIntConst);
ins->mSrc[0].mIntConst = ConstantFolding(ins->mOperator, ins->mDst.mType, ins->mSrc[0].mIntConst, pins->mSrc[0].mIntConst);
ins->mSrc[1].mTemp = pins->mSrc[1].mTemp;
}
}
@ -2337,7 +2348,7 @@ void InterCodeBasicBlock::CheckValueUsage(InterInstruction * ins, const GrowingI
ins->mSrc[0].mTemp >= 0 && tvalue[ins->mSrc[0].mTemp] && tvalue[ins->mSrc[0].mTemp]->mCode == IC_CONSTANT)
{
ins->mCode = IC_CONSTANT;
ins->mConst.mIntConst = ConstantFolding(ins->mOperator, tvalue[ins->mSrc[1].mTemp]->mConst.mIntConst, tvalue[ins->mSrc[0].mTemp]->mConst.mIntConst);
ins->mConst.mIntConst = ConstantFolding(ins->mOperator, ins->mDst.mType, tvalue[ins->mSrc[1].mTemp]->mConst.mIntConst, tvalue[ins->mSrc[0].mTemp]->mConst.mIntConst);
ins->mSrc[0].mTemp = -1;
ins->mSrc[1].mTemp = -1;
}

View File

@ -1,7 +1,7 @@
#include "InterCodeGenerator.h"
InterCodeGenerator::InterCodeGenerator(Errors* errors, Linker* linker)
: mErrors(errors), mLinker(linker), mForceNativeCode(false)
: mErrors(errors), mLinker(linker), mCompilerOptions(COPT_DEFAULT)
{
}
@ -2787,7 +2787,7 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod
dec->mLinkerObject = proc->mLinkerObject;
proc->mNumLocals = dec->mNumVars;
if (mForceNativeCode)
if (mCompilerOptions & COPT_NATIVE)
dec->mFlags |= DTF_NATIVE;
if (dec->mFlags & DTF_NATIVE)

View File

@ -3,6 +3,7 @@
#include "Parser.h"
#include "InterCode.h"
#include "Linker.h"
#include "CompilerTypes.h"
class InterCodeGenerator
{
@ -20,7 +21,7 @@ public:
{}
};
bool mForceNativeCode;
uint64 mCompilerOptions;
InterCodeProcedure* TranslateProcedure(InterCodeModule* mod, Expression* exp, Declaration * dec);
void TranslateAssembler(InterCodeModule* mod, Expression * exp, GrowingArray<Declaration *> * refvars);

View File

@ -6913,6 +6913,8 @@ bool NativeCodeBasicBlock::MoveLoadStoreUp(int at)
j--;
if ((mIns[j].mMode == ASMIM_ZERO_PAGE || mIns[j].mMode == ASMIM_INDIRECT_Y) && mIns[j].mAddress == mIns[at + 1].mAddress)
return false;
if (mIns[j].mMode == ASMIM_INDIRECT_Y && mIns[j].mAddress + 1 == mIns[at + 1].mAddress)
return false;
if (mIns[j].mMode == ASMIM_ZERO_PAGE && mIns[j].mAddress == mIns[at].mAddress && mIns[j].ChangesAddress())
return false;
if (mIns[j].mMode == ASMIM_ABSOLUTE_Y && mIns[j].mAddress <= mIns[at + 1].mAddress && mIns[j].mType == ASMIT_LDA && !mIns[j].mLinkerObject)

View File

@ -1299,8 +1299,6 @@ void Scanner::CharToken(void)
}
}
mTokenChar = mTokenChar;
mTokenInteger = mTokenChar;
if (mLine[mOffset] && mLine[mOffset] == '\'')

View File

@ -135,7 +135,20 @@ int main(int argc, const char** argv)
}
else if (arg[1] == 'n')
{
compiler->ForceNativeCode(true);
compiler->mCompilerOptions |= COPT_NATIVE;
}
else if (arg[1] == 'O')
{
if (arg[2] == '0')
compiler->mCompilerOptions &= ~(COPT_OPTIMIZE_ALL);
else if (arg[1] == '1' || arg[1] == 0)
compiler->mCompilerOptions |= COPT_OPTIMIZE_DEFAULT;
else if (arg[2] == '2')
compiler->mCompilerOptions |= COPT_OPTIMIZE_SPEED;
else if (arg[2] == '3')
compiler->mCompilerOptions |= COPT_OPTIMIZE_ALL;
else if (arg[2] == 's')
compiler->mCompilerOptions |= COPT_OPTIMIZE_SIZE;
}
else if (arg[1] == 'e')
{

View File

@ -168,6 +168,7 @@
<ClInclude Include="ByteCodeGenerator.h" />
<ClInclude Include="CompilationUnits.h" />
<ClInclude Include="Compiler.h" />
<ClInclude Include="CompilerTypes.h" />
<ClInclude Include="Declaration.h" />
<ClInclude Include="Disassembler.h" />
<ClInclude Include="Emulator.h" />

View File

@ -143,6 +143,9 @@
<ClInclude Include="GlobalAnalyzer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="CompilerTypes.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="oscar64.rc">