conditional compilation is dead, long live conditional ... · map preprocessor usage to c • macro...

Post on 18-Aug-2020

32 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

PaulGazzillo andShiyiWeiICSE-NIER2019

ConditionalCompilationIsDead,LongLiveConditionalCompilation!

@paul_gazzillo pgazz.com🔗

TheCPreprocessorCreatesaDilemma

• ConditionalcompilationimplementedwiththeCpreprocessor• Reallygreatforperformance• Reallybadforsoftwaretools

2

Goal:ReplacePreprocessorUsagewithCItself

• Easierforsoftwaretools• PreserveexistingCsoftware• How?

• NewClanguageconstructs• Automateconditionalcompilationwithcompileroptimizations

3

CUseHasGrown!

4

IEEESpectrumPopularityRankings,May2019

IoTDeveloperSurvey,EclipseFoundation2019

TIOBEPopularityRankings,May2019

ConditionalCompilationMakesReusePossible

• Linuxconfigurabletomanydevices• Noextraprogrammingneeded

5

Linux IoT devices in our home

7

Linux

CPreprocessorUsedExtensively

• Macrosusedabout1in4SLoC,ingeneral[Ernstetal1999]• Linuxv4.19(late2018)

• Developersuseittohand-optimizeobjectfilesize• CompilingallLinuxfeatureswouldmakeanenormousbinary

6

Sourcelinesofcode about12million

Preprocessormacrosdefined about1million

Preprocessordirectivesused about2million

Preprocessorconditionalblocks about60,000

ConditionalCompilationIsImplementedwiththePreprocessor

7

void irq_add(int *ops) {int irq = *ops;

}

int *ops = NULL;

ops = &irq_ops;

irq_add(ops);

#ifdef CONFIG_OF_IRQ_DOMAIN

#endif

#ifdef CONFIG_OF_IRQ

#endif

Configurationoptionstestedatbuild-time

VariabilityBugs:ExistenceDependsonConfigurationSettings

8

void irq_add(int *ops) {int irq = *ops;

}

int *ops = NULL;

ops = &irq_ops;

irq_add(ops);

#ifdef CONFIG_OF_IRQ_DOMAIN

#endif

#ifdef CONFIG_OF_IRQ

#endif

3.Nullpointererror insomeconfigurations

1.Initialize“ops”pointer

2.Onlysetinsomeconfigurations

Onlycertainconfigurationshavebugs

WhyDon’tWeJustUsea“Better”Language?

9

• Millions(billions?)ofSLoCinactive,widely-usedprojects

• RustandGowill(hopefully)supplantC,but…• Rusthasconfigurationmacros

• #[cfg]attributes• Gohasbuildconstraints

GreatResearchEffortsTacklingConditionalCompilation

• Newlanguage• Captureconditionalcompilationasvariability

• Similarchallengesforanalysistools

10

• “Lift”analysestoallconfigurations• State-of-the-artisintraproceduraldataflow

• MuchlefttomatchpureCtools,e.g.,• Points-toanalysis• Abstractinterpretation• Modelchecking• Separationlogic• Symbolicexecution

BestofBothWorlds:KeepCandAutomateConditionalCompilation

• Replacepreprocessorwithanewcompilerphase• Configurationmacros->programvalues• Conditionalcompilationbecomescompileroptimization

• Constantprop+deadcodeelimination=#ifdef

11

WhataretheConstructsoftheCombinedLanguage?

• Formalsemanticstypicallyreliesonwell-definedabstractsyntax• ThecombinedC/preprocessorlanguagehaswonkysyntax

• Someusageshouldprobablyberestricted

• Whatarethesemanticsofthecombinedlanguage?• CMod formallydefined#includeusage[Srivastavaetal.,TSE2008]

12

#define LBRACE {int main() LBRACE}

MapPreprocessorUsagetoC

• Macro->programvariable• #ifdef->Cconditional• Conditionalcompilation->deadcodeelimination• Transformationhasbeendonebefore[Iosif-Lazaretal.,Sci.Prog. 2017]

13

int *ops = NULL;#ifdef CONFIG_OF_IRQops = &irq_ops;#endifirq_add(ops);

bool CONFIG_OF_IRQ;int *ops = NULL;if (CONFIG_OF_IRQ) {ops = &irq_ops;}irq_add(ops);

SomeConstructsAreQuestionable

• Codeduplicationisawkward• Couldalterconditionstohaveonlytwobranches

• Shouldsuchcasesbeprohibited?

14

#ifdef CONFIG_PSAUXif (imajor == 10)

i = 31;else

#endifi = iminor – 32;

bool CONFIG_PSAUX;if (CONFIG_PSAUX) {

if (imajor == 10)i = 31;

elsei = iminor – 32;

} else {i = iminor – 32;

}

#ifdefsCanAppearAroundDeclarations

• #ifdefsfrequentlysurrounddeclarationsanddefinitions• Akintoadependenttype

• Typeandexistenceof"quota"dependsonprogramvariable

• Similarityobservedbeforein[Chenetal.,TOPLAS2014]

15

struct {u16 size;

#ifdef CONFIG_QUOTAint quota;

#endif}

bool CONFIG_QUOTA;struct {u16 size;

int __attribute__((config (CONFIG_SMP))) quota;

}

Conclusion

• Preprocessordilemma• Greatforperformance• Badfortools

• Goal:ReplacepreprocessorusagewithCitself• Automateconditionalcompilation• Extensionsforsomepreprocessorusecases

• Futurework• Languagedefinition:Whataretherightconstructs?Whatshouldbeillegal?• Empiricalevaluationofhowoftentranslationispossible• Newcompilerphaseandoptimizations

16

@paul_gazzillo pgazz.com🔗

top related