Skip to content

Commit 2b18cc2

Browse files
committed
rewrote confusing code; removed unnecessary assembly
1 parent 2790ed9 commit 2b18cc2

13 files changed

Lines changed: 54 additions & 240 deletions

File tree

CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ file(
5858
"src/ast.c"
5959
"src/binary.cpp"
6060
"src/llvm_ir.cpp"
61-
"src/optimize.cpp"
6261
)
6362

6463
# Remove raw lexer and parser source files if they're listed by GLOB

examples/addition.b

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222

2323
main () {
2424
auto a;
25-
a = !a;
2625
}
2726

2827

src/ast.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ static void print_node(ASTNode* node, int depth) {
192192

193193

194194
void print_ast() {
195-
for (int i = 0; i < ast_length; i++) print_node(generated_ast[i], 0);
195+
for (int i = 0; i < ast_length; i++)
196+
print_node(generated_ast[i], 0);
196197
printf("\n");
197198
}

src/binary.cpp

Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,18 @@
4040
#include <llvm/Support/FileSystem.h>
4141
#include <llvm/IR/LegacyPassManager.h>
4242

43+
#include "llvm/Passes/PassBuilder.h"
44+
#include "llvm/Passes/StandardInstrumentations.h"
45+
#include "llvm/Analysis/AliasAnalysis.h"
46+
#include "llvm/Transforms/Scalar.h"
47+
#include "llvm/Transforms/Utils.h"
4348

4449
#include <llvm/TargetParser/Host.h>
4550

51+
// Optimize TheModule with the provided optimization flags (-O3, -Os, etc)
52+
void optimize();
4653

4754
extern "C" void initialize_llvm() {
48-
4955
TheContext = std::make_unique<llvm::LLVMContext>();
5056
Builder = std::unique_ptr<llvm::IRBuilder<>>(new llvm::IRBuilder<>(*TheContext));
5157
TheModule = std::make_unique<llvm::Module>(ctx.inputFile, *TheContext);
@@ -62,11 +68,9 @@ extern "C" void initialize_llvm() {
6268
LLVMInitializeAArch64TargetMC();
6369
LLVMInitializeAArch64AsmParser();
6470
LLVMInitializeAArch64AsmPrinter();
65-
6671
}
6772

6873
extern "C" void export_asm() {
69-
7074
optimize(); // Apply any optimizations (will return if -O0)
7175

7276
std::string targetTriple = llvm::sys::getDefaultTargetTriple();
@@ -100,10 +104,8 @@ extern "C" void export_asm() {
100104

101105
// Set file type: object file (.o)
102106
#if defined(__APPLE__)
103-
// macOS (old API)
104107
llvm::CodeGenFileType fileType = llvm::CodeGenFileType::AssemblyFile;
105108
#else
106-
// Linux, Windows (new API)
107109
llvm::CodeGenFileType fileType = llvm::CGFT_AssemblyFile;
108110
#endif
109111

@@ -114,14 +116,10 @@ extern "C" void export_asm() {
114116

115117
pass.run(*TheModule);
116118
dest.flush();
117-
118-
llvm::outs() << "Wrote " << ctx.outputFilename << "\n";
119-
120119
}
121120

122121

123122
extern "C" void export_ir() {
124-
125123
optimize(); // Apply any optimizations (will return if -O0)
126124

127125
std::error_code EC;
@@ -135,7 +133,6 @@ extern "C" void export_ir() {
135133

136134

137135
extern "C" void generate_binary() {
138-
139136
optimize(); // Apply any optimizations (will return if -O0)
140137

141138
std::string targetTriple = llvm::sys::getDefaultTargetTriple();
@@ -181,10 +178,40 @@ extern "C" void generate_binary() {
181178

182179
pass.run(*TheModule);
183180
dest.flush();
184-
185-
llvm::outs() << "Wrote " << ctx.outputFilename << "\n";
186181
}
187182

188183

189-
190-
184+
void optimize() {
185+
if (!ctx.optimization) return;
186+
187+
// Create analysis managers
188+
llvm::LoopAnalysisManager LAM;
189+
llvm::FunctionAnalysisManager FAM;
190+
llvm::CGSCCAnalysisManager CGAM;
191+
llvm::ModuleAnalysisManager MAM;
192+
193+
// Create pass builder
194+
llvm::PassBuilder PB;
195+
196+
// Register analysis passes
197+
PB.registerModuleAnalyses(MAM);
198+
PB.registerCGSCCAnalyses(CGAM);
199+
PB.registerFunctionAnalyses(FAM);
200+
PB.registerLoopAnalyses(LAM);
201+
PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
202+
203+
llvm::ModulePassManager MPM;
204+
// Create optimization pipeline
205+
if (ctx.optimization == 1) // Mild optimization
206+
MPM = PB.buildPerModuleDefaultPipeline(llvm::OptimizationLevel::O1);
207+
else if (ctx.optimization == 2) // Moderate optimization
208+
MPM = PB.buildPerModuleDefaultPipeline(llvm::OptimizationLevel::O2);
209+
else if (ctx.optimization == 3) // Aggressive optimization
210+
MPM = PB.buildPerModuleDefaultPipeline(llvm::OptimizationLevel::O3);
211+
else if (ctx.optimization == 4) // Optimize for size
212+
MPM = PB.buildPerModuleDefaultPipeline(llvm::OptimizationLevel::Os);
213+
else if (ctx.optimization == 5) // Aggressively optimize for size
214+
MPM = PB.buildPerModuleDefaultPipeline(llvm::OptimizationLevel::Oz);
215+
216+
MPM.run(*TheModule, MAM);
217+
}

src/context.h

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,30 +26,20 @@
2626
extern "C" {
2727
#endif
2828

29-
3029
#include <stdbool.h>
3130

32-
3331
// Compiler options and state
3432
typedef struct CompilerContext {
3533
bool emitAssembly;
3634
bool emitLLVM;
37-
3835
char* outputFilename;
39-
4036
char* inputFile;
41-
4237
char* sourceText;
43-
4438
int optimization;
45-
4639
} CompilerContext;
4740

48-
49-
// Declare a global or external context variable, so other files can use it
5041
extern CompilerContext ctx;
5142

52-
5343
#ifdef __cplusplus
5444
}
5545
#endif

src/error.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424
#include <stdlib.h>
2525
#include "error.h"
2626

27+
#if defined(__GNUC__) || defined(__clang__)
28+
__attribute__((cold))
29+
#endif
2730
void error(const char *text, ...) {
2831
va_list args;
2932
va_start(args, text);
@@ -34,16 +37,14 @@ void error(const char *text, ...) {
3437
}
3538

3639
#if defined(__GNUC__) || defined(__clang__)
37-
__attribute__((noreturn))
40+
__attribute__((noreturn, cold))
3841
#endif
3942
void fatal_error(const char *text, ...) {
4043
va_list args;
4144
va_start(args, text);
4245
printf("bcc: " RED "error: " RESET);
4346
vprintf(text, args);
44-
printf("\n");
4547
va_end(args);
46-
47-
printf("bcc: " RED "error: " RESET "compilation failed\n");
48+
printf("\nbcc: " RED "error: " RESET "compilation failed\n");
4849
exit(1);
4950
}

src/error.h

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,21 +22,15 @@
2222
#ifndef ERROR_H
2323
#define ERROR_H
2424

25-
#include <stdarg.h>
26-
#include <stdio.h>
27-
2825
#define RED "\033[1;31m"
2926
#define RESET "\033[0m"
3027

3128
#ifdef __cplusplus
3229
extern "C" {
3330
#endif
3431

35-
/** Alert an error in the console; does not quit the program. */
36-
extern void error(const char *text, ...);
37-
38-
/** Alert an error in the console and quit the program. */
39-
extern void fatal_error(const char *text, ...);
32+
void error(const char *text, ...);
33+
void fatal_error(const char *text, ...);
4034

4135
#ifdef __cplusplus
4236
}

src/llvm.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,13 @@
2222
#ifndef LLVM_WRAPPER_H
2323
#define LLVM_WRAPPER_H
2424

25-
26-
2725
#ifdef __cplusplus
28-
29-
3026
#include <llvm/IR/LLVMContext.h>
3127
#include <llvm/IR/Module.h>
3228
#include <llvm/IR/IRBuilder.h>
3329
#include <llvm/IR/Value.h>
3430
#include <map>
3531

36-
37-
3832
extern std::unique_ptr<llvm::LLVMContext> TheContext;
3933
extern std::unique_ptr<llvm::IRBuilder<>> Builder;
4034
extern std::unique_ptr<llvm::Module> TheModule;
@@ -44,11 +38,8 @@ extern "C" {
4438
#endif
4539

4640
void generate_llvm_ir();
47-
4841
void initialize_llvm();
49-
5042
void optimize();
51-
5243
void generate_binary();
5344
void export_ir();
5445
void export_asm();

src/llvm_ir.cpp

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,6 @@
2121

2222
/// This file is used to create intermediate representation code for LLVM.
2323

24-
#include "llvm.h"
25-
#include "ast.h"
26-
#include "error.h"
27-
2824
#include <llvm/IR/LLVMContext.h>
2925
#include <llvm/IR/Module.h>
3026
#include <llvm/IR/IRBuilder.h>
@@ -36,31 +32,29 @@
3632
#include <cstring>
3733
#include <iostream>
3834

35+
#include "llvm.h"
36+
#include "ast.h"
37+
#include "error.h"
38+
3939
std::unique_ptr<llvm::LLVMContext> TheContext;
4040
std::unique_ptr<llvm::IRBuilder<>> Builder;
4141
std::unique_ptr<llvm::Module> TheModule;
4242

43-
4443
std::map<std::string, llvm::Value *> NamedValues;
4544
std::map<std::string, llvm::Value *> ExtrnValues;
4645

47-
48-
4946
std::map<std::string, llvm::Function *> FunctionValues;
5047
std::map<std::string, llvm::BasicBlock *> BasicBlockValues;
5148

52-
5349
static llvm::Value *LogErrorV(const char *Str) {
5450
llvm::errs() << "error: " << Str << "\n";
5551
return nullptr;
5652
}
5753

58-
5954
static inline llvm::Value* value_of(llvm::Value* alloca) {
6055
return Builder->CreateLoad(llvm::Type::getInt64Ty(*TheContext), alloca, "load");
6156
}
6257

63-
6458
/**
6559
* Stores whether a function being processed includes a return statement at the end.
6660
* If not, return(0); is added.
@@ -120,7 +114,6 @@ static llvm::Value* add_expression(ASTNode* node) {
120114
}
121115
case ASTNode::_FUNCTION_CALL:
122116
break;
123-
124117
case ASTNode::_NOT:
125118
{
126119
llvm::Value* not_value = Builder->CreateICmpEQ(
@@ -163,10 +156,8 @@ static llvm::Value* add_expression(ASTNode* node) {
163156
}
164157

165158
return nullptr;
166-
167159
}
168160

169-
170161
static void add_statement(ASTNode* node) {
171162

172163
switch (node->type) {

0 commit comments

Comments
 (0)